home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Future Workshop
/
Future Workshop.iso
/
multimed
/
qtw111
/
mplayer
/
moviewnd.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-11
|
138KB
|
3,384 lines
// ---------------------------------------------------------------------
//
// MovieWnd.c - Movie Player - QuickTime for Windows
//
// Version 1.0
//
// (c) 1988-1992 Apple Computer, Inc. All Rights Reserved.
//
// ---------------------------------------------------------------------
// Includes
// --------
#include <Windows.H> // Required by Windows
#include <commdlg.h> // Required for PRINTDLG struct
#include <stdio.h> // Required for sprintf routine
#include <sys\types.h> // Required for stat.h
#include <sys\stat.h> // Required for _stat routine
#include <math.h> // Required for abs()
#include <string.h> // Required for memset
#include <qtw.h> // Interface to QuickTime
#include <qtole.h> // Interface to qtole dll
#include "common.h" // Interface to common.c
#include "player.h" // Interface to other *.c files
#include "player.hr" // Defines used in *.rc files
// Constants
// ---------
#define GETINFOMOVIEPROP "Movie"
// Message-Persistent Data
// -----------------------
static struct // Hungarian notation: g
{WORD wMovieCount; // Used during enumeration for
// duplication checking
BOOL bCreating; // " " "
HWND hwndFirstDup; // " " "
WORD wMovieControllerHeight; // Height of movie controller
BOOL bUpdatingInfo; // Updating info dialog flag
char szSelectFormat[30]; // Info dialog selection format string
char szNoSelection[20]; // Info dialog "no selection" string
HICON hmovieIcon; // Movie frame icon
HCURSOR hcursor; // Current cursor. We need to set cursor
// during constrained resizing so class
// cursor must be set to NULL;
RECT rcResizeRect; // Rect used during constrained resizing
POINT ptCursorOffset; // Offset of cursor from edge of wnd rect
WORD wSides; // Combined width of vertical size borders
WORD wTBBorder; // Combined width of horizontal size borders
WORD wTopAndBottom; // Difference in height between movie and
// movie window. This includes the movie
// controller
WORD wSoundOnlyDefWidth; // Default width of a sound only movie
WORD wScaleWidth; // Scale width used in constrained resize
WORD wScaleHeight; // Scale height used in constrained resize
BOOL bFatResizeBorder; // Flag that causes resize border to be
// drawn 2 pixels thicker
WNDPROC lpOldGBProc; // Original grow box proc
WNDPROC lpNewGBProc; // Subclassed grow box proc
HWND hwndMaximizedMovie; // Handle of maximized movie wnd
BOOL bCapturedGrowBox; // TRUE if the grow box input has
// been captured
} g;
// Macros
// ----------------------
#define ISKEYDOWN( vKey ) (GetKeyState( (int) (vKey) ) < 0 )
// Exported callback functions
// ----------------------------
BOOL __export CALLBACK GetInfoDlgProc (HWND, UINT, WPARAM, LPARAM);
BOOL __export CALLBACK CheckDupEnumProc (HWND, LPARAM);
BOOL __export CALLBACK ActionFilter (MovieController, UINT, LPVOID, LONG);
BOOL __export CALLBACK MovieChildEnumProc (HWND, LPARAM);
LONG __export CALLBACK GBSubClassProc (HWND, UINT, WPARAM, LPARAM);
// Internal Function Declarations
// ------------------------------
static LONG NEAR PlayerMovieCreate (HWND, LPARAM );
static LONG NEAR PlayerEditCommands (HWND, WPARAM, WORD);
static LONG NEAR PlayerMovieCommands (HWND, WPARAM, WORD);
static LONG NEAR PrintFrame (HWND, LPPRINTDLG);
static VOID NEAR FillMovieInfo (HWND, NPMOVIEDATA);
static LONG NEAR StartTheMovie (NPMOVIEDATA);
static LONG NEAR StopTheMovie (NPMOVIEDATA);
static VOID NEAR UpdateInfoFileName (NPMOVIEDATA);
static VOID NEAR DisplayCurrentSelection (NPMOVIEDATA);
static LONG NEAR ResizeMovieAndWindow (HWND, BOOL, NPMOVIEDATA, WORD, WORD);
static LONG NEAR ResizeMovie (NPMOVIEDATA, WORD, WORD);
static LONG NEAR InitializePopupMenus (HWND, HMENU, int);
static LONG NEAR SetMinMaxInfo (HWND, NPMOVIEDATA, MINMAXINFO FAR *);
static VOID NEAR ActivateTheController (HWND, NPMOVIEDATA, BOOL);
static LONG NEAR PaintTheIcon (HWND, NPMOVIEDATA);
static HFONT NEAR MakeAnArialFont (HDC, int);
static VOID NEAR UpdateGBBoundsRect (HWND, NPMOVIEDATA);
static WORD NEAR InitializeResize (HWND, NPMOVIEDATA, WORD, POINT);
static VOID NEAR DrawTheFrameRect (LPRECT, BOOL);
static VOID NEAR MoveTheMovieResizeRect (HWND, NPMOVIEDATA,
WORD, POINT, BOOL);
static VOID NEAR GetProportionalDimensions (NPMOVIEDATA, PWORD, PWORD, BOOL);
static VOID NEAR AdjustForMinProportionalSize(HWND, NPMOVIEDATA,
LPWORD, LPWORD, BOOL);
static BOOL NEAR IsNormalSize (LPRECT, NPMOVIEDATA);
static BOOL NEAR SubclassTheGrowBox (HWND, NPMOVIEDATA);
static BOOL NEAR InitMaxWndGrowBoxResize (HWND, POINT);
static VOID NEAR MoveTheFrameResizeRect (HWND, POINT);
static LONG NEAR FixUpMovieTiling (HWND, NPMOVIEDATA, LPWINDOWPOS);
static VOID NEAR SetOptionsDefaults (HWND, NPMOVIEDATA);
static VOID NEAR PopulateOptionsStruct (HWND, NPMOVIEDATA);
// Function: PlayerMovieWndProc - Player Movie Window Procedure
// --------------------------------------------------------------------
// Parameters: As required by Microsoft Windows
//
// Returns: Via DefMDIChildProc
// --------------------------------------------------------------------
LONG __export CALLBACK PlayerMovieWndProc
(HWND hwndMovie, UINT message, WPARAM wParam, LPARAM lParam)
{
NPMOVIEDATA pMovieData; // Temp -> to movie data struct
HMOVIEDATA hMovieData; // Temp handle of movie data
WNDENUMPROC lpfnEnumMovies; // -> enumeration proc
NPMOVIEDATA pFirstMovieData; // Temp -> to movie data struct
// used during duplication processing
WORD wMovieWidth; // Movie normal width
WORD wMovieHeight; // Movie normal height
WORD wWidth; // Window width
WORD wHeight; // Window height
LRESULT lRetVal; // Return from DefMDIChildProc
POINT ptCursor; // Cursor position in screen coords.
LPQTOLE_OLEDATA lpOleData; // -> ole data
static WORD wResizeHitTestCode; // Equals the NC hit test code when
// resizing with SHIFT or CONTROL
pMovieData = (NPMOVIEDATA) GetWindowWord( hwndMovie, 0 );
if( pMovieData &&
MCIsPlayerMessage( pMovieData->mcMovieController,
hwndMovie, message, wParam, lParam ))
return DefMDIChildProc( hwndMovie, message, wParam, lParam );
switch( message ) {
case WM_CREATE:
// Load movie frame icon used by all instances
if( !g.hmovieIcon )
g.hmovieIcon = LoadIcon( PlayerQueryResources(),
MAKEINTRESOURCE( PLAYER_MOVIE_ICON ));
if( !g.hcursor )
g.hcursor = LoadCursor( NULL, IDC_ARROW );
return PlayerMovieCreate( hwndMovie, lParam );
case WM_SIZE:
if( !pMovieData )
break; // break to DefMDIChildProc
wMovieWidth = LOWORD( lParam );
if( HIWORD( lParam ) > g.wMovieControllerHeight )
wMovieHeight = HIWORD( lParam ) - g.wMovieControllerHeight;
else
wMovieHeight = 0;
if( wParam ) // Minimizing, maximizing, etc
{
if( wParam == SIZE_MAXIMIZED )
// If subclass failed, remove grow box
{
if( IsZoomed( PlayerQueryFrameWindow()) ||
!pMovieData->bGrowBoxSubclassed ) {
SetRectEmpty( &pMovieData->rcGrowBox );
MCDoAction( pMovieData->mcMovieController,
mcActionSetGrowBoxBounds, &pMovieData->rcGrowBox );
}
else if( pMovieData->wMinMaxEtc == SIZE_MINIMIZED ) { // Reset grow box bounds rect
UpdateGBBoundsRect( hwndMovie, pMovieData );
}
if( pMovieData->wMinMaxEtc == SIZE_MINIMIZED )
StartTheMovie( pMovieData );
g.hwndMaximizedMovie = hwndMovie;
ResizeMovie( pMovieData, wMovieWidth, wMovieHeight);
}
else if( wParam == SIZE_MINIMIZED ) {
SetRectEmpty( &pMovieData->rcGrowBox );
MCDoAction( pMovieData->mcMovieController,
mcActionSetGrowBoxBounds, &pMovieData->rcGrowBox );
StopTheMovie( pMovieData );
PaintTheIcon( hwndMovie, pMovieData );
}
pMovieData->wMinMaxEtc = wParam;
}
else if( pMovieData->wMinMaxEtc ) // restoring
{ // Reset grow box bounds rect
UpdateGBBoundsRect( hwndMovie, pMovieData );
if( pMovieData->wMinMaxEtc == SIZE_MAXIMIZED ) {
if( g.hwndMaximizedMovie == hwndMovie )
g.hwndMaximizedMovie = NULL;
ResizeMovie( pMovieData, wMovieWidth, wMovieHeight);
}
else if( pMovieData->wMinMaxEtc == SIZE_MINIMIZED ) {
StartTheMovie( pMovieData );
}
pMovieData->wMinMaxEtc = 0;
}
else if( pMovieData->bDisableSizeMsgProcessing ) { // Already processing create message, menu item or resizing
// to aspect ratio or even multiple of pixels according
// to key states in the last else under this message
pMovieData->bDisableSizeMsgProcessing = FALSE;
}
else {
ResizeMovie( pMovieData, wMovieWidth, wMovieHeight);
}
// Need this for movie controller to repaint correctly
// when window is small
if( wResizeHitTestCode ||
( PlayerQueryMDIAction() == PLAYER_WINDOW_TILE ))
InvalidateRect( hwndMovie, NULL, FALSE );
break; // break to DefMDIChildProc
case WM_MOVE:
if( !pMovieData ||
( pMovieData->wMinMaxEtc == SIZE_MAXIMIZED ) ||
( pMovieData->wMinMaxEtc == SIZE_MINIMIZED ))
break; // break to DefMDIChildProc
// Need to reset grow box bounds rect after a move because it is
// the client rect of the MDI frame window expressed in the client
// coordinates of the movie window
UpdateGBBoundsRect( hwndMovie, pMovieData );
break; // break to DefMDIChildProc
case WM_WINDOWPOSCHANGING:
if( pMovieData &&
( PlayerQueryMDIAction() == PLAYER_WINDOW_TILE )) {
FixUpMovieTiling( hwndMovie,
pMovieData, (LPWINDOWPOS) lParam );
}
break; // break to DefMDIChildProc
case WM_COMMAND:
switch( wParam ) {
case PLAYER_EDIT_COPY: // edit menu popup
case PLAYER_EDIT_OPTIONS:
case PLAYER_EDIT_CANCELSEL:
return PlayerEditCommands
( hwndMovie, wParam, HIWORD( lParam ));
case PLAYER_MOVIE_GETINFO: // movie menu popup
case PLAYER_MOVIE_STOPATEND:
case PLAYER_MOVIE_LOOP:
case PLAYER_MOVIE_BACKANDFORTH:
case PLAYER_MOVIE_PLAYSELONLY:
case PLAYER_MOVIE_HALFSIZE:
case PLAYER_MOVIE_NORMALSIZE:
case PLAYER_MOVIE_DOUBLESIZE:
case PLAYER_MOVIE_SHOWPOSTER:
return PlayerMovieCommands
( hwndMovie, wParam, HIWORD( lParam ));
default:
break; // break to DefMDIChildProc
}
break;
// WM_USER messages
case WM_PLAYER_PRINTFRAME:
return PrintFrame( hwndMovie, (LPPRINTDLG) lParam );
case WM_PLAYER_INITPOPUPS:
return InitializePopupMenus
( hwndMovie, (HMENU) wParam, (int) LOWORD(lParam) );
case WM_PLAYER_ACTIVATEMOVIE:
if( pMovieData ) {
SetMovieActive( pMovieData->mMovie, TRUE );
SetFocus( hwndMovie );
}
return 0L;
case WM_PLAYER_ACTIVATECONTROLLER:
if( pMovieData && pMovieData->mcMovieController )
ActivateTheController( hwndMovie, pMovieData, TRUE );
return 0L;
case WM_PLAYER_PLAYTHEMOVIE: // Send by frame window when it is
// iconized or restored
if( pMovieData &&
( pMovieData->wMinMaxEtc != SIZE_MINIMIZED )) {
if( (BOOL) wParam )
StartTheMovie( pMovieData );
else
StopTheMovie( pMovieData );
}
return 0L;
case WM_PLAYER_UPDATEGBBOUNDSRECT:
// Frame window sends this message when size changes
if( !pMovieData ||
( pMovieData->wMinMaxEtc == SIZE_MINIMIZED ))
return 0L;
UpdateGBBoundsRect( hwndMovie, pMovieData );
return 0L;
// end WM_USER messages
case WM_NCACTIVATE:
if( pMovieData && pMovieData->mcMovieController ) { // Activate or deactivate the controller
if( (BOOL) wParam ) { // Post message to introduce a delay so that
// activation occurs after mouse click.
// Activate is called directly if PostMessage fails
if( !PostMessage( hwndMovie,
WM_PLAYER_ACTIVATECONTROLLER, TRUE, 0L ))
ActivateTheController( hwndMovie, pMovieData, TRUE );
}
else {
ActivateTheController( hwndMovie, pMovieData, FALSE );
}
}
break; // break to DefMDIChildProc
case WM_GETMINMAXINFO:
SetMinMaxInfo( hwndMovie, pMovieData, (MINMAXINFO FAR*) lParam );
break; // break to DefMDIChildProc
case WM_QUERYDRAGICON:
return MAKELONG( g.hmovieIcon, 0 );
case WM_NCHITTEST:
lRetVal = DefMDIChildProc
( hwndMovie, message, wParam, lParam );
if( pMovieData && pMovieData->bSoundOnly ) {
switch( LOWORD( lRetVal )) {
case HTTOP:
case HTBOTTOM:
return 0L;
case HTTOPLEFT:
case HTBOTTOMLEFT:
return HTLEFT;
case HTTOPRIGHT:
case HTBOTTOMRIGHT:
return HTRIGHT;
default:
return lRetVal;
}
}
else
return lRetVal;
case WM_NCLBUTTONDOWN: // We must do all border drag resizing
// so we can do the constrained resizing
if( pMovieData &&
( wResizeHitTestCode = InitializeResize
( hwndMovie, pMovieData, wParam, MAKEPOINT( lParam )))) {
SetCapture( hwndMovie );
MoveTheMovieResizeRect( hwndMovie, pMovieData,
wResizeHitTestCode, MAKEPOINT( lParam ), TRUE );
return 0L;
}
break; // break to DefMDIChildProc
case WM_MOUSEMOVE:
if( wResizeHitTestCode ) {
ptCursor = MAKEPOINT( lParam );
ClientToScreen( hwndMovie, &ptCursor );
MoveTheMovieResizeRect( hwndMovie, pMovieData,
wResizeHitTestCode, ptCursor, FALSE );
}
else if( g.bCapturedGrowBox ) // This move is initiated in the
// grow box subclass proc.
{
ptCursor = MAKEPOINT( lParam );
ClientToScreen( hwndMovie, &ptCursor );
MoveTheFrameResizeRect( hwndMovie, ptCursor );
}
SetCursor( g.hcursor );
return 0L;
case WM_LBUTTONUP:
if( wResizeHitTestCode ) {
DrawTheFrameRect( &g.rcResizeRect, g.bFatResizeBorder );
ReleaseCapture();
DrawTheFrameRect( NULL, FALSE ); // This cleans up
ClipCursor( NULL );
g.hcursor = LoadCursor( NULL, IDC_ARROW );
if( !pMovieData->bSoundOnly &&
( ISKEYDOWN( VK_CONTROL ) || ISKEYDOWN( VK_SHIFT ))) {
wWidth = g.rcResizeRect.right - g.rcResizeRect.left;
wHeight = g.rcResizeRect.bottom - g.rcResizeRect.top;
AdjustForMinProportionalSize
( hwndMovie, pMovieData,
&wWidth, &wHeight, ISKEYDOWN( VK_CONTROL ));
g.rcResizeRect.right = g.rcResizeRect.left + wWidth;
g.rcResizeRect.bottom = g.rcResizeRect.top + wHeight;
}
MapWindowPoints( HWND_DESKTOP, PlayerQueryClientWindow(),
(LPPOINT) &g.rcResizeRect, 2 );
MoveWindow( hwndMovie,
g.rcResizeRect.left, g.rcResizeRect.top,
g.rcResizeRect.right - g.rcResizeRect.left,
g.rcResizeRect.bottom - g.rcResizeRect.top, TRUE );
// This needs to be after the MoveWindow call
wResizeHitTestCode = 0;
}
else if( g.bCapturedGrowBox ) // This move is initiated in the
// grow box subclass proc.
{
g.bCapturedGrowBox = FALSE;
DrawTheFrameRect( &g.rcResizeRect, FALSE );
ReleaseCapture();
DrawTheFrameRect( NULL, FALSE ); // This cleans up
ClipCursor( NULL );
MoveWindow( PlayerQueryFrameWindow(),
g.rcResizeRect.left, g.rcResizeRect.top,
g.rcResizeRect.right - g.rcResizeRect.left,
g.rcResizeRect.bottom - g.rcResizeRect.top, TRUE );
}
return 0L;
case WM_PAINT:
// We paint the icon but QTW takes care of all the painting
// otherwise.
if( pMovieData && IsIconic( hwndMovie ))
return PaintTheIcon( hwndMovie, pMovieData );
break; // break to DefMDIChildProc
case WM_DESTROY:
if( ( lpOleData = PlayerQueryOleData()) && lpOleData->lpqtoleServer )
PopulateOptionsStruct( hwndMovie, pMovieData );
break; // break to DefMDIChildProc
case WM_NCDESTROY:
if( !pMovieData )
break;
if( pMovieData->lpFilterProc ) {
MCSetActionFilter
( pMovieData->mcMovieController, NULL, 0L );
FreeProcInstance( (FARPROC ) pMovieData->lpFilterProc );
pMovieData->lpFilterProc = NULL;
}
if( pMovieData->hwndGetInfo )
DestroyWindow( pMovieData->hwndGetInfo );
if( pMovieData->mcMovieController )
DisposeMovieController( pMovieData->mcMovieController );
if( pMovieData->mMovie )
DisposeMovie( pMovieData->mMovie );
// Last instance destroys icon and grow box subclass proc
if( PlayerQueryNumMovies() <= 1 ) {
if( g.hmovieIcon )
DestroyIcon( g.hmovieIcon );
g.hmovieIcon = NULL;
// Free the grow box subclass proc
if( g.lpNewGBProc ) {
FreeProcInstance( (FARPROC) g.lpNewGBProc );
g.lpNewGBProc = NULL;
}
g.lpOldGBProc = NULL;
}
else { // Check for duplicates
g.wMovieCount = 0;
g.bCreating = FALSE;
g.hwndFirstDup = NULL;
if( lpfnEnumMovies = (WNDENUMPROC) MakeProcInstance
( (FARPROC) CheckDupEnumProc, PlayerQueryInstance())) {
EnumChildWindows( PlayerQueryClientWindow(),
lpfnEnumMovies, MAKELPARAM( hwndMovie, 0 ));
FreeProcInstance( (FARPROC) lpfnEnumMovies );
}
// if no dups, eliminate :1 on first
// hwndFirstDup is set in CheckDupEnumProc
if( ( g.wMovieCount == 1 ) && g.hwndFirstDup &&
( pFirstMovieData = (NPMOVIEDATA)
GetWindowWord( g.hwndFirstDup, 0 ))) {
pFirstMovieData->wDuplicationIndex = 0;
SetWindowText( g.hwndFirstDup,
pFirstMovieData->szMovieName );
}
}
// Tell OLE that window is closed. Movie has been disposed
// qtole.dll used hwndObject so don't null the handle in struct
pMovieData->qtoleOptions.mMovie = NULL;
if( ( lpOleData = PlayerQueryOleData()) && lpOleData->lpqtoleServer )
QTOLE_ClosingDocWnd( lpOleData,
(LPQTOLE_OPTIONS) &pMovieData->qtoleOptions );
LocalUnlock( hMovieData =
(HMOVIEDATA) LocalHandle( pMovieData ));
LocalFree( hMovieData );
SetWindowWord( hwndMovie, 0, 0);
// Update the movie count in the frame window globals
SendMessage( PlayerQueryFrameWindow(),
WM_PLAYER_MOVIEDELETED, (WPARAM) hwndMovie, 0L );
break; // break to DefMDIChildProc
}
return DefMDIChildProc( hwndMovie, message, wParam, lParam );
}
// Function: PlayerMovieCreate - process WM_CREATE message
// --------------------------------------------------------------------
// Parameters: HWND hwndMovie; Handle of movie window
// LPARAM lParam; lParam of WM_CREATE message
//
// Returns: 0 if OK, else returns -1 to kill app
// --------------------------------------------------------------------
static LONG NEAR PlayerMovieCreate( HWND hwndMovie, LPARAM lParam )
{
NPMOVIEDATA pMovieData; // Temp -> to movie data struct
HMOVIEDATA hMovieData; // Handle to movie data struct
LPMDICREATESTRUCT lpmdicreate; // MDI create struct
MovieFile movMovieFile; // Movie file handle
char szBuffer[MAX_PATH_LEN]; // Temp buffer
struct _stat statbuf; // File statictics struct
WORD wIDString; // Resource string id
DWORD dwBytes; // File size
OSErr oserr; // Error return
RECT rcMovie; // Movie rect
RECT rcWindow; // Window rect
RECT rcController; // Controller rect
POINT ptCorner; // Upper Left corner of movie wnd
WORD wWidth; // Width of window
WORD wHeight; // Height of window
RECT rcclientClient; // Client rect of MDI client wnd
int nDiff; // Temp
WNDENUMPROC lpfnEnumMovies; // -> to enumeration proc
LPSTR lpName; // Temp -> movie name
LONG lStyle; // Temp window style
UserData udUserData; // Handle to user data
HGLOBAL ghMem; // Global mem used to get 'loop' user data
LONG lSizeData; // Size of 'loop' user data
LPSTR lpUserData; // -> 'loop' user data
int i; // Loop counter
QTOLE_OPENWND qtoleOpenWnd; // Ole open wnd struct
LPQTOLE_OLEDATA lpOleData; // -> ole data
int nLoop;
pMovieData = (NPMOVIEDATA) NULL;
if( !(hMovieData = (HMOVIEDATA)
LocalAlloc( LPTR, sizeof( MOVIEDATASTRUCT )))) {
CommonTellUser( PlayerQueryResources(),
PLAYER_STRING_NOMEMORY, NULL, MB_OK );
goto Failed;
}
pMovieData = (NPMOVIEDATA) LocalLock( hMovieData );
SetWindowWord( hwndMovie, 0, (WORD) pMovieData );
// mdi struct filled before call to MDI create in LaunchMovieWnd
lpmdicreate = (LPMDICREATESTRUCT)
((LPCREATESTRUCT) lParam)->lpCreateParams;
lstrcpy( pMovieData->szMoviePath, (LPSTR) lpmdicreate -> lParam );
lstrcpy( pMovieData->szMovieName, (LPSTR) lpmdicreate -> szTitle );
// Strip off and save extension so that name fits better
// on title bar of window
pMovieData->szMovieExt[0] = '\0';
lpName = pMovieData->szMovieName;
while( *lpName ) {
if( *lpName == '.' ) {
lstrcpy( pMovieData->szMovieExt, lpName );
*lpName = '\0';
SetWindowText( hwndMovie, pMovieData->szMovieName );
break;
}
else
lpName = AnsiNext( lpName );
}
if( ( oserr = OpenMovieFile( pMovieData->szMoviePath,
&movMovieFile, OF_READ )) == 0 ) {
oserr = NewMovieFromFile( &pMovieData->mMovie,
movMovieFile, NULL, NULL, 0, NULL );
CloseMovieFile( movMovieFile );
}
if( oserr ) {
if( oserr == insufficientMemory )
wIDString = PLAYER_STRING_NOMEMORY;
else if( oserr == invalidDataRef )
wIDString = PLAYER_STRING_INVALIDDATAREF;
else
wIDString = PLAYER_STRING_NEWMOVIEERR;
CommonTellUser( PlayerQueryResources(),
wIDString, PLAYER_STRING_CAPTION,
MB_OK, (LPSTR) lpmdicreate -> szTitle );
goto Failed;
}
// Check for duplicates. Fix up titles if necessary
// Initialize globals used during enumeration
g.wMovieCount = 1;
g.bCreating = TRUE;
if( ( PlayerQueryNumMovies() > 0 ) &&
( lpfnEnumMovies = (WNDENUMPROC) MakeProcInstance
( (FARPROC) CheckDupEnumProc, PlayerQueryInstance()))) {
EnumChildWindows( PlayerQueryClientWindow(),
lpfnEnumMovies, MAKELPARAM( hwndMovie, 0 ));
FreeProcInstance( (FARPROC) lpfnEnumMovies );
// Fix up title if duplicate
// Title of 1st dup is fixed up during enum
if( g.wMovieCount > 1 ) {
pMovieData->wDuplicationIndex = g.wMovieCount;
wsprintf( szBuffer, "%s:%u",
(LPSTR) pMovieData->szMovieName,
pMovieData->wDuplicationIndex );
SetWindowText( hwndMovie, szBuffer );
}
}
// file size Note: _stat path name is in OEM char set
lstrcpy( szBuffer, pMovieData->szMoviePath );
AnsiToOem( szBuffer, szBuffer );
if( (_stat( szBuffer, &statbuf )) == 0 ) {
if( statbuf.st_size < 1000L ) {
dwBytes = (DWORD) statbuf.st_size;
wIDString = PLAYER_STRING_SIZEBYTES;
}
else {
dwBytes = (DWORD) ( statbuf.st_size / 1000L );
wIDString = PLAYER_STRING_SIZEKBYTES;
}
LoadString( PlayerQueryResources(),
wIDString, szBuffer, sizeof( szBuffer ));
wsprintf( pMovieData->szFileSize, szBuffer, dwBytes );
}
pMovieData->bSoundOnly = FALSE;
pMovieData->idMovieInfo.idSize = sizeof( ImageDescription );
oserr = GetVideoInfo( pMovieData->mMovie, &pMovieData->idMovieInfo );
if( oserr == noVideoTrackInMovie ) {
pMovieData->bSoundOnly = TRUE;
}
else if( oserr ) {
CommonTellUser( PlayerQueryResources(),
PLAYER_STRING_NOINFO, PLAYER_STRING_CAPTION, MB_OK );
goto Failed;
}
pMovieData->sdSoundInfo.descSize = sizeof( SoundDescription );
pMovieData->oserrSoundInfo =
GetSoundInfo( pMovieData->mMovie, &pMovieData->sdSoundInfo );
// Set copy option default values
SetOptionsDefaults( hwndMovie, pMovieData );
// Instantiate the movie controller
if( !pMovieData->bSoundOnly ) // Call only if there is video
{
GetMovieBox( pMovieData->mMovie, &rcMovie );
OffsetRect( &rcMovie, -rcMovie.left, -rcMovie.top );
// Now resize window if default option is half or double size
if( pMovieData->qtoleOptions.bSizeHalf ) {
rcMovie.right /= 2;
rcMovie.bottom /= 2;
}
else if( pMovieData->qtoleOptions.bSizeDouble ) {
rcMovie.right *= 2;
rcMovie.bottom *= 2;
}
}
// Movie with no video or no rect gets a default width to pass to
// NewMovieController
if( pMovieData->bSoundOnly || IsRectEmpty( &rcMovie )) {
rcMovie.left = rcMovie.top = 0;
rcMovie.right = 8 * GetSystemMetrics( SM_CXVSCROLL );
rcMovie.bottom = 0;
}
if( !( pMovieData->mcMovieController =
NewMovieController( pMovieData->mMovie, &rcMovie,
mcTopLeftMovie | mcScaleMovieToFit, hwndMovie ))) {
CommonTellUser( PlayerQueryResources(),
PLAYER_STRING_NOCONTROLLER, PLAYER_STRING_CAPTION, MB_OK );
goto Failed;
}
MCDoAction( pMovieData->mcMovieController, mcActionPlay, (LPVOID) 0 );
// Subclass the movie controller grow box for use when a
// movie window is maximized
pMovieData->bGrowBoxSubclassed =
SubclassTheGrowBox( hwndMovie, pMovieData );
// Override loop mode depending on user data
ghMem = NULL;
nLoop = 0;
if( ( udUserData = GetMovieUserData( pMovieData->mMovie )) &&
( CountUserDataType( udUserData,
QTFOURCC( 'L', 'O', 'O', 'P' )) > 0 )) {
pMovieData->qtoleOptions.bLoop = TRUE;
pMovieData->qtoleOptions.bLoopPalindrome = FALSE;
if( ( ghMem = GlobalAlloc( GHND, 16L )) &&
!GetUserData( udUserData, &ghMem,
QTFOURCC( 'L', 'O', 'O', 'P' ), 1L, &lSizeData ) &&
( lSizeData > 0L )) {
lpUserData = (LPSTR) GlobalLock( ghMem );
for( i=0; i < lSizeData; i++ ) {
if( *lpUserData++ != '\0' ) {
pMovieData->qtoleOptions.bLoop = FALSE;
pMovieData->qtoleOptions.bLoopPalindrome = TRUE;
break;
}
}
GlobalUnlock( ghMem );
}
if( ghMem )
GlobalFree( ghMem );
}
// Now tell the movie controller about the loop mode
MCDoAction( pMovieData->mcMovieController, mcActionSetLooping,
(LPVOID) ( pMovieData->qtoleOptions.bLoop ||
pMovieData->qtoleOptions.bLoopPalindrome ));
MCDoAction( pMovieData->mcMovieController, mcActionSetLoopIsPalindrome,
(LPVOID) pMovieData->qtoleOptions.bLoopPalindrome );
// Assume that the controller is attached
// Get the default UL corner of window
GetWindowRect( hwndMovie, &rcWindow );
MapWindowPoints( HWND_DESKTOP, PlayerQueryClientWindow(),
(LPPOINT) &rcWindow, 2 );
ptCorner = *((LPPOINT) &rcWindow.left );
// This includes the movie AND the moviecontroller rect
MCGetControllerBoundsRect
( pMovieData->mcMovieController, &rcController );
rcWindow = rcController;
// At this point rcController == client rect of window
// Save controller height
g.wMovieControllerHeight =
( rcWindow.bottom - rcWindow.top ) -
( rcMovie.bottom - rcMovie.top );
// Remove maximize box if sound only movie
if( pMovieData->bSoundOnly ) {
lStyle = GetWindowLong( hwndMovie, GWL_STYLE );
lStyle &= ~WS_MAXIMIZEBOX;
SetWindowLong( hwndMovie, GWL_STYLE, lStyle );
}
AdjustWindowRect( &rcWindow,
GetWindowLong( hwndMovie, GWL_STYLE ), FALSE );
// rcWindow now contains the size of the window
wWidth = rcWindow.right - rcWindow.left;
wHeight = rcWindow.bottom - rcWindow.top;
OffsetRect( &rcWindow, ptCorner.x - rcWindow.left,
ptCorner.y - rcWindow.top );
// rcWindow now contains the resized window positioned so that
// the UL corner is at the MDI default position
// Now stash some dimensions needed later. Only need to do this once
if( pMovieData->bSoundOnly && !g.wSoundOnlyDefWidth ) {
g.wSoundOnlyDefWidth = wWidth;
}
if( !g.wSides ) {
g.wSides = ( rcWindow.right - rcWindow.left ) -
( rcController.right - rcController.left );
g.wTBBorder = ( rcWindow.bottom - rcWindow.top ) -
( rcController.bottom - rcController.top );
g.wTopAndBottom = g.wMovieControllerHeight + g.wTBBorder;
}
// Now see if it will fit on screen.
GetClientRect( PlayerQueryClientWindow(), &rcclientClient );
if( rcWindow.right > rcclientClient.right ) { // extends beyond right border
// Try to shift it to the left
nDiff = rcclientClient.right - wWidth;
rcWindow.left = max( 0, nDiff );
rcWindow.right = rcWindow.left + wWidth;
}
if( rcWindow.bottom > rcclientClient.bottom ) { // extends beyond bottom
// Try to shift it up
nDiff = rcclientClient.bottom - wHeight;
rcWindow.top = max( 0, nDiff );
rcWindow.bottom = rcWindow.top + wHeight;
}
// Resize the window after disabling WM_SIZE processing
// In the unusual case that the controller is smaller than
// the smallest possible client, we stretch the controller
pMovieData->bDisableSizeMsgProcessing = TRUE;
MoveWindow( hwndMovie,
rcWindow.left, rcWindow.top, wWidth, wHeight, FALSE );
// If movie is smaller than minimum window size, resize movie to
// fill the window
GetClientRect( hwndMovie, &rcWindow );
if( !EqualRect( &rcWindow, &rcController ))
MCSetControllerBoundsRect
( pMovieData->mcMovieController, &rcWindow );
// Size message turns this off, turn in on again for next
// WM_SIZE message generated by standard "create a window" processing
pMovieData->bDisableSizeMsgProcessing = TRUE;
// Post message to activate the movie
// Post message is used to avoid a extra paint of the movie which
// causes a flash during the window creation
// SendMessage is called if PostMessage fails
if( !PostMessage( hwndMovie, WM_PLAYER_ACTIVATEMOVIE, 0, 0L ))
SendMessage( hwndMovie, WM_PLAYER_ACTIVATEMOVIE, 0, 0L );
// Set Action filter to look for selection changes and grow box resizing.
// Do this after earlier resizing to avoid having to block filter messages
// generated during creation
if( pMovieData->lpFilterProc =
(MCActionFilter) MakeProcInstance
( (FARPROC) ActionFilter, PlayerQueryInstance())) {
MCSetActionFilter( pMovieData->mcMovieController,
pMovieData->lpFilterProc, MAKELONG( pMovieData, hwndMovie ));
}
// Tell qtole.dll that movie has been opened
if( ( lpOleData = PlayerQueryOleData()) && lpOleData->lpqtoleServer ) {
qtoleOpenWnd.lStructSize = sizeof( qtoleOpenWnd );
qtoleOpenWnd.lVersion = VERSION_1;
qtoleOpenWnd.wObjectType = MOVIE_OBJECT;
qtoleOpenWnd.hwndObject = hwndMovie;
qtoleOpenWnd.lpObjectPath = pMovieData->szMoviePath;
qtoleOpenWnd.lpObjectName = pMovieData->szMovieName;
QTOLE_OpeningNewObjectWnd( lpOleData, &qtoleOpenWnd );
}
return 0L;
Failed:
SetWindowWord( hwndMovie, 0, 0 );
if( pMovieData )
LocalUnlock( hMovieData );
if( hMovieData )
LocalFree ( hMovieData );
return -1;
}
// Function: CheckDupEnumProc - Checks for duplicate pictures and
// fixes up titles if there are any
// --------------------------------------------------------------------
// Parameters: As required by Microsoft Windows
//
// Returns: Always TRUE;
// --------------------------------------------------------------------
BOOL __export CALLBACK CheckDupEnumProc( HWND hwnd, LPARAM lParam )
// Look for duplicate pictures. Test is on path rather than just name
{
char szBuffer[50]; // Temp buffer
HWND hwndActiveMovie; // Handle of active movie wnd
NPMOVIEDATA pMovieData; // -> enum wnd movie data struct
NPMOVIEDATA pActiveMovieData; // -> active wnd movie data struct
// Skip active movie
if( ( hwndActiveMovie = (HWND) LOWORD( lParam )) == hwnd )
return TRUE;
if( !GetClassName( hwnd, szBuffer, sizeof( szBuffer )) ||
lstrcmpi( szBuffer, PLAYER_MOVIE_CLASS ))
return TRUE;
pMovieData = (NPMOVIEDATA) GetWindowWord( hwnd, 0 );
pActiveMovieData = (NPMOVIEDATA) GetWindowWord( hwndActiveMovie, 0 );
if( !pMovieData || !pActiveMovieData )
return TRUE;
if( !lstrcmpi( pMovieData->szMoviePath,
pActiveMovieData->szMoviePath )) { // Found a duplicate
g.wMovieCount++;
if( g.bCreating ) {
if( pMovieData->wDuplicationIndex == 0 ) {
pMovieData->wDuplicationIndex = 1;
wsprintf( szBuffer, "%s:%u",
(LPSTR) pMovieData->szMovieName,
pMovieData->wDuplicationIndex );
SetWindowText( hwnd, szBuffer );
}
}
else {
if( pMovieData->wDuplicationIndex >
pActiveMovieData->wDuplicationIndex ) {
pMovieData->wDuplicationIndex--;
wsprintf( szBuffer, "%s:%u",
(LPSTR) pMovieData->szMovieName,
pMovieData->wDuplicationIndex );
SetWindowText( hwnd, szBuffer );
}
if( pMovieData->wDuplicationIndex == 1 )
g.hwndFirstDup = hwnd;
}
if( pMovieData->hwndGetInfo &&
!PostMessage( pMovieData->hwndGetInfo,
WM_PLAYER_INFO_UPDATEFILENAME, 0, 0L ))
SendMessage( pMovieData->hwndGetInfo,
WM_PLAYER_INFO_UPDATEFILENAME, 0, 0L );
}
return TRUE;
}
// Function: PlayerEditCommands - Process WM_COMMAND, Edit popup messages
// --------------------------------------------------------------------
// Parameters: HWND hwndMovie; Handle of movie window
// WORD wIDItem; Menu or control id
// WORD wNotifyCode; notification message
//
// Returns: LONG generally 0L
// --------------------------------------------------------------------
static LONG NEAR PlayerEditCommands
(HWND hwndMovie, WPARAM wIDItem, WORD wNotifyCode )
{
NPMOVIEDATA pMovieData; // -> movie data struct
TimeRecord trZeroTime; // Zero time
PicHandle phFrame; // Pic handle of copied frame
DIBHandle hbmpDIB; // Handle of DIB bitmap passed to clipboard
OSErr oserr; // Errror return value
WORD wIDString; // ID of error string
HDC hdc; // Device context of window
HDC hdcMem; // Memory dc
ImageDescription idPicInfo; // Image description struct
HBITMAP hbmpCompatible; // Mem bitmap
HBITMAP hbmpSave; // Prev bitmap
RECT rcFrame; // Rect of frame being copied
TimeRecord trMovieTime; // Temp time record
HPALETTE hpal; // Palette handle
LPQTOLE_OLEDATA lpOleData; // -> ole data
if( !(pMovieData = (NPMOVIEDATA) GetWindowWord( hwndMovie, 0 ))) {
CommonTellUser( PlayerQueryResources(),
PLAYER_STRING_NOMOVIEDATA, PLAYER_STRING_CAPTION, MB_OK );
return 0L;
}
switch( wIDItem ) {
case PLAYER_EDIT_COPY:
if( IsIconic( hwndMovie ))
return 0L;
// If ole, let ole do the copy
if( ( lpOleData = PlayerQueryOleData()) && lpOleData->lpqtoleServer ) {
PopulateOptionsStruct( hwndMovie, pMovieData );
QTOLE_Copy( lpOleData, (LPQTOLE_OPTIONS) &pMovieData->qtoleOptions );
// We must compensate for an error in certain drivers by
// resetting the palette back the way we found it
MCDoAction( pMovieData->mcMovieController,
mcActionSetFlags, (LPVOID) mcFlagsUseWindowPalette );
}
else // No ole so do copy here
{
hdcMem = NULL;
hbmpCompatible = NULL;
hbmpSave = NULL;
phFrame = NULL;
if( !( hdc = GetDC( hwndMovie )) ||
!( hdcMem = CreateCompatibleDC( hdc )) ||
!( phFrame = GetMoviePict( pMovieData->mMovie,
GetMovieTime( pMovieData->mMovie, &trMovieTime )))) {
wIDString = PLAYER_STRING_COPYFAILED;
goto CopyFailed;
}
if( oserr = GetPictureInfo( phFrame, &idPicInfo )) {
wIDString = PLAYER_STRING_COPYFAILED;
goto CopyFailed;
}
if( !( hbmpCompatible = CreateCompatibleBitmap( hdc,
idPicInfo.width, idPicInfo.height ))) {
wIDString = PLAYER_STRING_NOMEMORY;
goto CopyFailed;
}
if( !( hbmpSave = SelectObject( hdcMem, hbmpCompatible ))) {
wIDString = PLAYER_STRING_COPYFAILED;
goto CopyFailed;
}
rcFrame.left = rcFrame.top = 0;
rcFrame.right = idPicInfo.width;
rcFrame.bottom = idPicInfo.height;
if( oserr = DrawPicture( hdcMem, phFrame, &rcFrame, NULL )) {
wIDString = PLAYER_STRING_COPYFAILED;
goto CopyFailed;
}
SelectObject( hdcMem, hbmpSave );
hbmpSave = NULL;
DeleteDC( hdcMem );
hdcMem = NULL;
OpenClipboard( hwndMovie );
EmptyClipboard();
if( !SetClipboardData( CF_BITMAP, hbmpCompatible )) {
wIDString = PLAYER_STRING_COPYFAILED;
goto CopyFailed;
}
hbmpCompatible = NULL; // Now belongs to clipboard
// Now add palette if movie has a palette
if( ( hpal = GetPicturePalette( phFrame )) &&
!SetClipboardData( CF_PALETTE, hpal ))
DeleteObject( hpal );
hpal = NULL;
// Now try to add DIBitmap to clipboard
if( ( hbmpDIB = PictureToDIB( phFrame )) &&
!SetClipboardData( CF_DIB, hbmpDIB ))
GlobalFree( hbmpDIB );
hbmpDIB = NULL;
CloseClipboard();
if( phFrame )
DisposePicture( phFrame );
ReleaseDC( hwndMovie, hdc );
return 0L;
CopyFailed:
CommonTellUser( PlayerQueryResources(),
wIDString, PLAYER_STRING_CAPTION, MB_OK );
if( hbmpSave )
SelectObject( hdcMem, hbmpSave );
if( hdc )
ReleaseDC( hwndMovie, hdc );
if( hdcMem )
DeleteDC( hdcMem );
if( hbmpCompatible )
DeleteObject( hbmpCompatible );
if( phFrame )
DisposePicture( phFrame );
if( hbmpDIB )
GlobalFree( hbmpDIB );
}
return 0L;
case PLAYER_EDIT_OPTIONS:
PopulateOptionsStruct( hwndMovie, pMovieData );
if( PlayerGetOptions( hwndMovie, &pMovieData->qtoleOptions ))
UpdateMovieForOptions( hwndMovie, pMovieData, FALSE );
return 0L;
case PLAYER_EDIT_CANCELSEL:
trZeroTime.scale = GetMovieTimeScale( pMovieData->mMovie );
trZeroTime.value.dwHi = 0L;
trZeroTime.value.dwLo = (DWORD) -1L;
trZeroTime.base = TIMEBASE_DEFAULT;
// Set beginning of selection to zero
MCDoAction( pMovieData->mcMovieController,
mcActionSetSelectionBegin, (LPVOID) &trZeroTime );
// Set duration to zero
trZeroTime.value.dwLo = 0L;
trZeroTime.base = NULL;
MCDoAction( pMovieData->mcMovieController,
mcActionSetSelectionDuration, (LPVOID) &trZeroTime );
return 0L;
}
return 0L; // should never get here
}
// Function: PlayerMovieCommands - Process WM_COMMAND, Movie popup messages
// --------------------------------------------------------------------
// Parameters: HWND hwndMovie; Handle of movie window
// WORD wIDItem; Menu or control id
// WORD wNotifyCode; notification message
//
// Returns: LONG generally 0L
// --------------------------------------------------------------------
static LONG NEAR PlayerMovieCommands
( HWND hwndMovie, WPARAM wIDItem, WORD wNotifyCode )
{
NPMOVIEDATA pMovieData; // -> movie data struct
DLGPROC lpDlgProc; // -> info dialog proc function
HWND hwndInfoDialog; // HWND of info dialog box
TimeRecord trPosterTime; // Poster time
BOOL bPlaySelectionOnly; // Flag
if( !(pMovieData = (NPMOVIEDATA) GetWindowWord( hwndMovie, 0 ))) {
CommonTellUser( PlayerQueryResources(),
PLAYER_STRING_NOMOVIEDATA, PLAYER_STRING_CAPTION, MB_OK );
return 0L;
}
switch( wIDItem ) {
case PLAYER_MOVIE_GETINFO:
if( pMovieData->hwndGetInfo )
SetFocus( pMovieData->hwndGetInfo );
else if( !(lpDlgProc = (DLGPROC) MakeProcInstance
( (FARPROC) GetInfoDlgProc, PlayerQueryInstance())) ||
!(hwndInfoDialog =
CreateDialog( PlayerQueryResources(),
MAKEINTRESOURCE( PLAYER_DLG_GETINFO ),
PlayerQueryFrameWindow(), lpDlgProc ))) {
CommonTellUser( PlayerQueryResources(),
PLAYER_STRING_NOMEMORY, NULL, MB_OK );
}
return 0L;
case PLAYER_MOVIE_STOPATEND:
MCDoAction( pMovieData->mcMovieController,
mcActionSetLoopIsPalindrome, (LPVOID) FALSE );
MCDoAction( pMovieData->mcMovieController,
mcActionSetLooping, (LPVOID) FALSE );
return 0L;
case PLAYER_MOVIE_LOOP:
MCDoAction( pMovieData->mcMovieController,
mcActionSetLooping, (LPVOID) TRUE );
MCDoAction( pMovieData->mcMovieController,
mcActionSetLoopIsPalindrome, (LPVOID) FALSE );
return 0L;
case PLAYER_MOVIE_BACKANDFORTH:
MCDoAction( pMovieData->mcMovieController,
mcActionSetLooping, (LPVOID) TRUE );
MCDoAction( pMovieData->mcMovieController,
mcActionSetLoopIsPalindrome, (LPVOID) TRUE );
return 0L;
case PLAYER_MOVIE_PLAYSELONLY:
MCDoAction( pMovieData->mcMovieController,
mcActionGetPlaySelection,
(LPVOID) &bPlaySelectionOnly );
MCDoAction( pMovieData->mcMovieController,
mcActionSetPlaySelection,
(LPVOID) !bPlaySelectionOnly );
return 0L;
// For next 3 cases, if window is maximized or minimized, we need to
// restore before resizing so that Windows knows that the window is
// no longer maximized or minimized
case PLAYER_MOVIE_HALFSIZE:
if( ( pMovieData->wMinMaxEtc == SIZE_MAXIMIZED ) ||
( pMovieData->wMinMaxEtc == SIZE_MINIMIZED ))
ShowWindow( hwndMovie, SW_SHOWNORMAL );
return ResizeMovieAndWindow( hwndMovie, TRUE, pMovieData,
pMovieData->idMovieInfo.width / 2,
pMovieData->idMovieInfo.height / 2 );
case PLAYER_MOVIE_NORMALSIZE:
if( ( pMovieData->wMinMaxEtc == SIZE_MAXIMIZED ) ||
( pMovieData->wMinMaxEtc == SIZE_MINIMIZED ))
ShowWindow( hwndMovie, SW_SHOWNORMAL );
return ResizeMovieAndWindow( hwndMovie, TRUE, pMovieData,
pMovieData->idMovieInfo.width,
pMovieData->idMovieInfo.height );
case PLAYER_MOVIE_DOUBLESIZE:
if( ( pMovieData->wMinMaxEtc == SIZE_MAXIMIZED ) ||
( pMovieData->wMinMaxEtc == SIZE_MINIMIZED ))
ShowWindow( hwndMovie, SW_SHOWNORMAL );
return ResizeMovieAndWindow( hwndMovie, TRUE, pMovieData,
pMovieData->idMovieInfo.width * 2,
pMovieData->idMovieInfo.height * 2 );
case PLAYER_MOVIE_SHOWPOSTER:
trPosterTime.value.dwHi = 0L;
trPosterTime.value.dwLo =
GetMoviePosterTime( pMovieData->mMovie );
trPosterTime.scale = GetMovieTimeScale( pMovieData->mMovie );
trPosterTime.base = TIMEBASE_DEFAULT;
// Stop the movie
MCDoAction( pMovieData->mcMovieController,
mcActionPlay, (LPVOID) 0 );
// Go to poster time
MCDoAction( pMovieData->mcMovieController,
mcActionGoToTime, (LPVOID) &trPosterTime );
return 0L;
}
return 0L; // should never get here
}
//// the following are some utility routines
// Function: ActivateTheController - Activates or deactivates the movie
// controller
// --------------------------------------------------------------------
// Parameters: HWND hwndMovie Handle of movie window
// NPMOVIEDATA pMovieData -> to movie data struct
// BOOL bActivate Activate flag
//
// Returns: VOID
// --------------------------------------------------------------------
static VOID NEAR ActivateTheController
( HWND hwndMovie, NPMOVIEDATA pMovieData, BOOL bActivate )
{
short nVol; // Sound volume
if( bActivate && ( hwndMovie != (HWND) SendMessage
( PlayerQueryClientWindow(), WM_MDIGETACTIVE, 0, 0L )))
return;
MCActivate( pMovieData->mcMovieController, hwndMovie, bActivate );
MCDoAction( pMovieData->mcMovieController,
mcActionSetKeysEnabled, (LPVOID) bActivate );
if( bActivate ) // RealizePalette only if activating
{
MCDoAction( pMovieData->mcMovieController,
mcActionSetFlags, (LPVOID) mcFlagsUseWindowPalette );
// InvalidateRect is needed to cause repainting in certain
// situations when the window is iconic
InvalidateRect( hwndMovie, NULL, TRUE );
}
MCDoAction( pMovieData->mcMovieController,
mcActionGetVolume, (LPVOID) &nVol );
if( ( bActivate && ( nVol < 0 )) || ( !bActivate && ( nVol > 0 )))
MCDoAction( pMovieData->mcMovieController,
mcActionSetVolume, (LPVOID) -nVol );
}
// Function: StartTheMovie - Starts the movie
// --------------------------------------------------------------------
// Parameters: NPMOVIEDATA pMovieData -> movie data struct
//
// Returns: LONG always 0L
// --------------------------------------------------------------------
static LONG NEAR StartTheMovie( NPMOVIEDATA pMovieData )
{ // Reactivate the movie
SetMovieActive( pMovieData->mMovie, TRUE );
// Restart the movie if it was playing
if( pMovieData->lfxSavePlayRate )
MCDoAction( pMovieData->mcMovieController,
mcActionPlay, (LPVOID) pMovieData->lfxSavePlayRate );
return 0L;
}
// Function: StopTheMovie - Stops the movie
// --------------------------------------------------------------------
// Parameters: NPMOVIEDATA pMovieData -> movie data struct
//
// Returns: LONG always 0L
// --------------------------------------------------------------------
static LONG NEAR StopTheMovie( NPMOVIEDATA pMovieData )
{ // save the play rate
MCDoAction( pMovieData->mcMovieController,
mcActionGetPlayRate, (LPVOID) &pMovieData->lfxSavePlayRate );
// Stop the movie
MCDoAction( pMovieData->mcMovieController,
mcActionPlay, (LPVOID) 0 );
// Deactivate movie to prevent painting over the icon
SetMovieActive( pMovieData->mMovie, FALSE );
return 0L;
}
// Function: PaintTheIcon - processes the WM_PAINT message when iconic
// --------------------------------------------------------------------
// Parameters: HWND hwndPicture Handle of Picture window
// NPMOVIEDATA pMovieData -> movie data struct
//
// Returns: LONG 0L
// --------------------------------------------------------------------
static LONG NEAR PaintTheIcon( HWND hwndMovie, NPMOVIEDATA pMovieData )
{
HCURSOR hcursorSave; // Saved cursor
HBRUSH hbrush; // Temp background brush
PicHandle phPoster; // Pic handle
PAINTSTRUCT ps; // Paint struct
RECT rcPicRect; // Proportional pic rect
WORD wIconWidth; // Icon width
WORD wIconHeight; // Icon height
WORD wProportional; // Temp
static RECT rcIcon = {
2, 2, 34, 34}; // Rect used in painting icon
// Make sure the entire window rect is invalidated
InvalidateRect( hwndMovie, NULL, FALSE );
if( !BeginPaint( hwndMovie, &ps ))
return 0L;
if( !pMovieData->mMovie ) {
EndPaint( hwndMovie, &ps );
return 0L;
}
hcursorSave = SetCursor( LoadCursor( NULL, IDC_WAIT ));
if( pMovieData->bSoundOnly ) { // Erase the entire background since there is no picture
if( hbrush = CreateSolidBrush( GetSysColor( COLOR_APPWORKSPACE ))) {
FillRect( ps.hdc, &ps.rcPaint, hbrush );
DeleteObject( hbrush );
}
// Now draw the film strip icon
if( g.hmovieIcon )
DrawIcon( ps.hdc, 2, 2, g.hmovieIcon );
}
else {
if( phPoster = GetMoviePosterPict( pMovieData->mMovie )) {
rcPicRect = rcIcon;
wIconWidth = rcIcon.right - rcIcon.left;
wIconHeight = rcIcon.bottom - rcIcon.top;
if( pMovieData->idMovieInfo.width >
pMovieData->idMovieInfo.height ) {
wProportional = MulDiv( wIconHeight,
pMovieData->idMovieInfo.width,
pMovieData->idMovieInfo.height );
rcPicRect.left -= ( wProportional - wIconWidth ) / 2;
rcPicRect.right = rcPicRect.left + wProportional;
}
else if( pMovieData->idMovieInfo.width <
pMovieData->idMovieInfo.height ) {
wProportional = MulDiv( wIconWidth,
pMovieData->idMovieInfo.height,
pMovieData->idMovieInfo.width );
rcPicRect.top -= ( wProportional - wIconHeight ) / 2;
rcPicRect.bottom = rcPicRect.top + wProportional;
}
// Draw the poster frame
if( DrawPicture( ps.hdc, phPoster, &rcPicRect, NULL )) {
CommonTellUser( PlayerQueryResources(),
PLAYER_STRING_DRAWPICFAILED,
PLAYER_STRING_CAPTION, MB_OK );
// Validate rect to prevent infinite loop
ValidateRect( hwndMovie, NULL );
DisposePicture( phPoster );
SetCursor( hcursorSave );
EndPaint( hwndMovie, &ps );
return 0L;
}
else {
DisposePicture( phPoster );
}
}
// Now draw the film strip icon
if( g.hmovieIcon )
DrawIcon( ps.hdc, 2, 2, g.hmovieIcon );
// Now paint background
ExcludeClipRect( ps.hdc, rcIcon.left, rcIcon.top,
rcIcon.right, rcIcon.bottom );
// COLOR_APPWORKSPACE is standard MDI background color
if( hbrush = CreateSolidBrush( GetSysColor( COLOR_APPWORKSPACE ))) {
FillRect( ps.hdc, &ps.rcPaint, hbrush );
DeleteObject( hbrush );
}
}
SetCursor( hcursorSave );
EndPaint( hwndMovie, &ps );
return 0L;
}
// Function: PrintFrame - prints indicated number of copies of
// the selected frame at normal size
// --------------------------------------------------------------------
// Parameters: HWND hwndMovie Handle of movie window
// LPPRINTDLG lppd -> to PRINTDLG struct created
// print common dialog
//
// Returns: LONG 0L if successful
// --------------------------------------------------------------------
static LONG NEAR PrintFrame( HWND hwndMovie, LPPRINTDLG lppd )
{
NPMOVIEDATA pMovieData; // -> movie data struct
WORD i; // Counter
DOCINFO diDocInfo; // Document info struct
PicHandle phFrame; // Pichandle of current frame
BOOL bError; // Error flag
int nError; // Error return
OSErr oserr; // Error return from DrawPicture
int xRes; // Horz printer resolution
int yRes; // Vert printer resolution
int xOffset; // Horz offset to center picture
int yOffset; // Vert offset to center picture
RECT rcFrame; // Frame rect
WORD wWidthPage; // Width of printed page in pixels
WORD wHeightPage; // Height of printed page in pixels
TimeRecord trMovieTime; // Temp time record
if( !(pMovieData = (NPMOVIEDATA) GetWindowWord( hwndMovie, 0 ))) {
CommonTellUser( PlayerQueryResources(),
PLAYER_STRING_NOMOVIEDATA, PLAYER_STRING_CAPTION, MB_OK );
// Turn off not reported flag
return SP_ERROR & ~SP_NOTREPORTED;
}
diDocInfo.cbSize = sizeof( DOCINFO );
diDocInfo.lpszDocName = pMovieData->szMovieName;
diDocInfo.lpszOutput = (LPSTR) NULL;
if( !(phFrame = GetMoviePict( pMovieData->mMovie,
GetMovieTime( pMovieData->mMovie, &trMovieTime )))) {
CommonTellUser( PlayerQueryResources(),
PLAYER_STRING_GETPICTFAILED, PLAYER_STRING_CAPTION, MB_OK );
// Turn off not reported flag
return SP_ERROR & ~SP_NOTREPORTED;
}
wWidthPage = GetDeviceCaps( lppd->hDC, HORZRES );
wHeightPage = GetDeviceCaps( lppd->hDC, VERTRES );
xRes = MulDiv( wWidthPage, 254,
GetDeviceCaps( lppd->hDC, HORZSIZE ) * 10 );
yRes = MulDiv( wHeightPage, 254,
GetDeviceCaps( lppd->hDC, VERTSIZE ) * 10 );
rcFrame.right = MulDiv( pMovieData->idMovieInfo.width,
xRes, HIWORD( pMovieData->idMovieInfo.hRes ));
rcFrame.bottom = MulDiv( pMovieData->idMovieInfo.height,
yRes, HIWORD( pMovieData->idMovieInfo.vRes ));
rcFrame.left = rcFrame.top = 0;
// Now make sure that frame fits on page
if( rcFrame.right > (int) wWidthPage ) {
rcFrame.bottom = MulDiv( rcFrame.bottom,
wWidthPage, rcFrame.right );
rcFrame.right = wWidthPage;
}
if( rcFrame.bottom > (int) wHeightPage ) {
rcFrame.right = MulDiv( rcFrame.right,
wHeightPage, rcFrame.bottom );
rcFrame.bottom = wHeightPage;
}
// Now center rect on page
xOffset = (wWidthPage - rcFrame.right ) / 2;
yOffset = (wHeightPage - rcFrame.bottom ) / 2;
OffsetRect( &rcFrame, xOffset, yOffset );
bError = FALSE;
oserr = 0L;
nError = SP_ERROR;
if( StartDoc( lppd->hDC, &diDocInfo ) > 0 ) {
for( i=0; (i < lppd->nCopies) && !bError; i++ ) {
if( StartPage( lppd->hDC ) > 0) {
if( (oserr = DrawPicture
( lppd->hDC, phFrame, &rcFrame, NULL )) != 0L ) {
AbortDoc( lppd->hDC );
bError = TRUE;
}
else if( (nError = EndPage( lppd->hDC )) < 0 )
bError = TRUE;
}
else
bError = TRUE;
}
}
else
bError = TRUE;
if( !bError )
EndDoc( lppd->hDC );
if( phFrame )
DisposePicture( phFrame );
return (LONG) nError;
}
// Function: SetMinMaxInfo - Processes the WM_GETMINMAXINFO message
// --------------------------------------------------------------------
// Parameters: HWND hwndMovie Handle of movie wnd
// NPMOVIEDATA pMovieData -> to movie data
// MINMAXINFO FAR* lpmmi -> to minmaxinfo struct
//
// Returns: LONG always 0L
// --------------------------------------------------------------------
static LONG NEAR SetMinMaxInfo
( HWND hwndMovie, NPMOVIEDATA pMovieData, MINMAXINFO FAR* lpmmi )
{
RECT rcWindow; // Movie window rect
if( PlayerQueryMDIAction() == PLAYER_WINDOW_CASCADE ) {
GetWindowRect( hwndMovie, &rcWindow );
lpmmi->ptMaxTrackSize.x = rcWindow.right - rcWindow.left;
lpmmi->ptMaxTrackSize.y = rcWindow.bottom - rcWindow.top;
lpmmi->ptMinTrackSize = lpmmi->ptMaxTrackSize;
lpmmi->ptMaxSize = lpmmi->ptMaxTrackSize;
}
else {
lpmmi->ptMinTrackSize.x = 3 * GetSystemMetrics( SM_CXSIZE );
lpmmi->ptMinTrackSize.y = GetSystemMetrics( SM_CYCAPTION ) +
g.wMovieControllerHeight +
2 * GetSystemMetrics( SM_CYFRAME );
// Disable vertical resizing if sound only movie
if( pMovieData && pMovieData->bSoundOnly ) {
lpmmi->ptMinTrackSize.y -= 2;
lpmmi->ptMaxTrackSize.y = lpmmi->ptMinTrackSize.y;
}
}
return 0L;
}
// Function: GetInfoDlgProc - Get Info dialog proc
// --------------------------------------------------------------------
// Parameters: As required by Microsoft Windows
//
// Returns: As required by Microsoft Windows
// --------------------------------------------------------------------
BOOL __export CALLBACK GetInfoDlgProc
( HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam )
{
NPMOVIEDATA pMovieData; // -> movie data struct
HWND hwndMovie; // HWND of movie window
HWND hwndCtl; // Handle of control
HDC hdc; // DC of dialog
int nHeight; // Height of control text font
switch( message ) {
case WM_INITDIALOG:
hwndMovie = (HWND) SendMessage
( PlayerQueryClientWindow(), WM_MDIGETACTIVE, 0, 0L );
// Use property to associate movie window handle with
// info dialog. This is necessary because MDI makes frame
// window the parent of all dialogs no matter what handle
// is used in the CreateDialog call
SetProp( hdlg, GETINFOMOVIEPROP, (HANDLE) hwndMovie );
if( pMovieData = (NPMOVIEDATA) GetWindowWord( hwndMovie, 0 )) {
pMovieData->hwndGetInfo = hdlg;
// Cache selection strings to speed up updates
if( !g.szSelectFormat[0] )
LoadString( PlayerQueryResources(),
PLAYER_STRING_SELECTION,
g.szSelectFormat, sizeof( g.szSelectFormat ));
if( !g.szNoSelection[0] )
LoadString( PlayerQueryResources(),
PLAYER_STRING_NOSELECTION,
g.szNoSelection, sizeof( g.szNoSelection ));
if( hdc = GetDC( hdlg )) {
nHeight = -MulDiv( 8, GetDeviceCaps( hdc, LOGPIXELSY ), 72 );
if( pMovieData->hfInfo = MakeAnArialFont( hdc, nHeight )) {
hwndCtl = GetWindow( hdlg, GW_CHILD );
while( hwndCtl ) {
if( GetDlgCtrlID( hwndCtl ) != IDOK )
SendMessage( hwndCtl, WM_SETFONT,
(WPARAM) pMovieData->hfInfo, 0 );
hwndCtl = GetWindow( hwndCtl, GW_HWNDNEXT );
}
}
ReleaseDC( hdlg, hdc );
}
FillMovieInfo( hdlg, pMovieData );
}
return TRUE;
case WM_ACTIVATE:
PlayerSetActiveModeless( wParam, hdlg );
return TRUE;
// WM_USER messages
case WM_PLAYER_INFO_UPDATEFILENAME:
hwndMovie = (HWND) GetProp( hdlg, GETINFOMOVIEPROP );
if( IsWindow( hwndMovie ) && ( pMovieData =
(NPMOVIEDATA) GetWindowWord( hwndMovie, 0 )))
UpdateInfoFileName( pMovieData );
break;
case WM_PLAYER_INFO_UPDATE:
hwndMovie = (HWND) GetProp( hdlg, GETINFOMOVIEPROP );
if( IsWindow( hwndMovie ) && ( pMovieData =
(NPMOVIEDATA) GetWindowWord( hwndMovie, 0 )))
FillMovieInfo( hdlg, pMovieData );
break;
// End WM_USER messages
case WM_COMMAND:
return DestroyWindow( hdlg );
case WM_DESTROY:
hwndMovie = (HWND) GetProp( hdlg, GETINFOMOVIEPROP );
if( IsWindow( hwndMovie ) && ( pMovieData =
(NPMOVIEDATA) GetWindowWord( hwndMovie, 0 ))) {
pMovieData->hwndGetInfo = NULL;
if( pMovieData->hfInfo )
DeleteObject( pMovieData->hfInfo );
pMovieData->hfInfo = NULL;
}
RemoveProp( hdlg, GETINFOMOVIEPROP );
break;
}
return FALSE;
}
// Function: FillMovieInfo - Fills dialog controls with movie data
// --------------------------------------------------------------------
// Parameters: HWND hdlg Handle of dialog wnd
// NPMOVIEDATA pMovieData -> movie data struct
//
// Returns: VOID
// --------------------------------------------------------------------
static VOID NEAR FillMovieInfo( HWND hdlg, NPMOVIEDATA pMovieData )
{
char szBuffer[MAX_PATH_LEN]; // Buffer
char szFormat[30]; // Format buffer
TimeValue tvDuration; // Duration of movie
double fTimeScale; // Timescale
RECT rcMovie; // Current movie rect
DWORD dwColors; // Number of colors
char szCompressor[sizeof(DWORD) + 1]; // compressor type
WORD wIDString; // Colors string id
DWORD dwRate; // Sound sample rate
DWORD dwKRate; // Sound sample rate
char szNull[] = ""; // Static null string
g.bUpdatingInfo = TRUE;
// Movie name: Append duplication index if > 0
UpdateInfoFileName( pMovieData );
// file size
SetDlgItemText( hdlg, MOVIE_INFO_FILESIZE, pMovieData->szFileSize );
// Get movie time scale
if( ( fTimeScale = (double)
GetMovieTimeScale( pMovieData->mMovie )) != 0. ) { // Do these only if timescale != zero to avoid divide by 0
// Movie duration
tvDuration = GetMovieDuration( pMovieData->mMovie );
LoadString( PlayerQueryResources(), PLAYER_STRING_DURATION,
szFormat, sizeof( szFormat ));
sprintf( szBuffer, szFormat, tvDuration / fTimeScale );
SetDlgItemText( hdlg, MOVIE_INFO_DURATION, szBuffer );
// Current selection
DisplayCurrentSelection( pMovieData );
}
if( !pMovieData->bSoundOnly ) { // Current size
LoadString( PlayerQueryResources(), PLAYER_STRING_WANDH,
szFormat, sizeof( szFormat ));
GetMovieBox( pMovieData->mMovie, &rcMovie );
wsprintf( szBuffer, szFormat, rcMovie.right - rcMovie.left,
rcMovie.bottom - rcMovie.top );
SetDlgItemText( hdlg, MOVIE_INFO_CURSIZE, szBuffer );
// Normal Width and Height
wsprintf( szBuffer, szFormat,
pMovieData->idMovieInfo.width,
pMovieData->idMovieInfo.height );
SetDlgItemText( hdlg, MOVIE_INFO_WANDH, szBuffer );
wsprintf( szBuffer, szFormat, pMovieData->idMovieInfo.height );
// Resolution
if( HIWORD( pMovieData->idMovieInfo.hRes ) != 0 ) {
LoadString( PlayerQueryResources(),
PLAYER_STRING_RESOLUTION, szFormat, sizeof( szFormat ));
wsprintf( szBuffer, szFormat,
HIWORD( pMovieData->idMovieInfo.hRes ));
}
else {
LoadString( PlayerQueryResources(),
PLAYER_STRING_NORESOLUTION, szBuffer, sizeof( szBuffer ));
}
SetDlgItemText( hdlg, MOVIE_INFO_RESOLUTION, szBuffer );
// Normal colors
switch( pMovieData->idMovieInfo.depth ) {
case 1: // Black and White
wIDString = PLAYER_STRING_CLRS_BANDW;
break;
case 1 + 32: // 2 Grays
wIDString = PLAYER_STRING_CLRS_2GRAYS;
break;
case 2: // 4 Colors
wIDString = PLAYER_STRING_CLRS_4COLORS;
break;
case 2 + 32: // 4 Grays
wIDString = PLAYER_STRING_CLRS_4GRAYS;
break;
case 4: // 16 Colors
wIDString = PLAYER_STRING_CLRS_16COLORS;
break;
case 4 + 32: // 16 Grays
wIDString = PLAYER_STRING_CLRS_16GRAYS;
break;
case 8: // 256 Colors
wIDString = PLAYER_STRING_CLRS_256COLORS;
break;
case 8 + 32: // 256 Grays
wIDString = PLAYER_STRING_CLRS_256GRAYS;
break;
case 16: // Thousands of Colors
wIDString = PLAYER_STRING_CLRS_THOUSANDS;
break;
case 24: // Millions of Colors
wIDString = PLAYER_STRING_CLRS_MILLIONS;
break;
case 32: // Millions of Colors+
wIDString = PLAYER_STRING_CLRS_MILLNSPLUS;
break;
default:
wIDString = 0xffff;
if( pMovieData->idMovieInfo.depth < 32 ) {
LoadString( PlayerQueryResources(), PLAYER_STRING_COLORS,
szFormat, sizeof( szFormat ));
dwColors = 1L << pMovieData->idMovieInfo.depth;
wsprintf( szBuffer, szFormat, dwColors );
}
else {
szBuffer[0] = '\0';
}
break;
}
if( wIDString != 0xffff )
LoadString( PlayerQueryResources(), wIDString,
szBuffer, sizeof( szBuffer ));
SetDlgItemText( hdlg, MOVIE_INFO_COLORS, szBuffer );
// Compressor type. Use .name if not empty
if( pMovieData->idMovieInfo.name[0] ) {
SetDlgItemText( hdlg, MOVIE_INFO_COMPRESSOR,
pMovieData->idMovieInfo.name );
}
else // Check Codec type for 'raw'
{ // Compressor type is stored as a DWORD. i.e. 'jpeg'
// Spaces in "raw ", "rle " etc are necessary !!!
if( pMovieData->idMovieInfo.CodecType ) {
*((PDWORD) &szCompressor) = pMovieData->idMovieInfo.CodecType;
szCompressor[ sizeof(DWORD) ] = '\0';
}
szBuffer[0] = '\0';
if( !pMovieData->idMovieInfo.CodecType ||
!lstrcmpi( szCompressor, "raw " ))
wIDString = PLAYER_STRING_CODEC_NONE;
else if( !lstrcmpi( szCompressor, "jpeg" ))
wIDString = PLAYER_STRING_CODEC_PHOTO;
else if( !lstrcmpi( szCompressor, "rle " ))
wIDString = PLAYER_STRING_CODEC_ANIMATION;
else if( !lstrcmpi( szCompressor, "smc " ))
wIDString = PLAYER_STRING_CODEC_GRAPHICS;
else if( !lstrcmpi( szCompressor, "rpza" ))
wIDString = PLAYER_STRING_CODEC_VIDEO;
else if( !lstrcmpi( szCompressor, "cvid" ))
wIDString = PLAYER_STRING_CODEC_CVID;
else
wIDString = PLAYER_STRING_CODEC_NONE;
LoadString( PlayerQueryResources(), wIDString,
szBuffer, sizeof( szBuffer ));
SetDlgItemText( hdlg, MOVIE_INFO_COMPRESSOR, szBuffer );
}
}
else {
LoadString( PlayerQueryResources(),
PLAYER_STRING_NOVIDEO, szBuffer, sizeof( szBuffer ));
SetDlgItemText( hdlg, MOVIE_INFO_CURSIZE, szBuffer );
SetDlgItemText( hdlg, MOVIE_INFO_WANDH, szNull );
SetDlgItemText( hdlg, MOVIE_INFO_RESOLUTION, szNull );
SetDlgItemText( hdlg, MOVIE_INFO_COLORS, szNull );
SetDlgItemText( hdlg, MOVIE_INFO_COMPRESSOR, szNull );
}
// Sound info
if( pMovieData->oserrSoundInfo == noSoundTrackInMovie ) {
LoadString( PlayerQueryResources(),
PLAYER_STRING_SND_NOSOUND, szBuffer, sizeof( szBuffer ));
SetDlgItemText( hdlg, MOVIE_INFO_SND_NUMCHANNELS, szBuffer );
SetDlgItemText( hdlg, MOVIE_INFO_SND_SOUNDQUALITY, szNull );
}
else if( pMovieData->oserrSoundInfo == soundSupportNotAvailable ) {
LoadString( PlayerQueryResources(),
PLAYER_STRING_SND_NOCARD, szBuffer, sizeof( szBuffer ));
SetDlgItemText( hdlg, MOVIE_INFO_SND_NUMCHANNELS, szBuffer );
SetDlgItemText( hdlg, MOVIE_INFO_SND_SOUNDQUALITY, szNull );
}
else if( pMovieData->oserrSoundInfo ) { // GetSoundInfo call failed so doen't write anything
}
else { // Num of channels
if( pMovieData->sdSoundInfo.numChannels == 1 )
LoadString( PlayerQueryResources(), PLAYER_STRING_SND_MONO,
szBuffer, sizeof( szBuffer ));
else
LoadString( PlayerQueryResources(), PLAYER_STRING_SND_STEREO,
szBuffer, sizeof( szBuffer ));
SetDlgItemText( hdlg, MOVIE_INFO_SND_NUMCHANNELS, szBuffer );
// Sample size and rate
LoadString( PlayerQueryResources(),
PLAYER_STRING_SND_SOUNDQUALITY, szFormat, sizeof( szFormat ));
dwRate = ((DWORD) pMovieData->sdSoundInfo.sampleRate ) / 65536L;
dwKRate = dwRate / 1000;
dwRate -= dwKRate * 1000;
wsprintf( szBuffer, szFormat,
pMovieData->sdSoundInfo.sampleSize, dwKRate, dwRate );
SetDlgItemText( hdlg, MOVIE_INFO_SND_SOUNDQUALITY, szBuffer );
}
// End sound info
g.bUpdatingInfo = FALSE;
return;
}
// Function: UpdateInfoFileName - Updates the file name with the current
// instance count in the info dialog
// --------------------- -----------------------------------------------
// Parameters: NPMOVIEDATA pMovieData -> to MOVIEDATA struct
//
// Returns: VOID
// --------------------------------------------------------------------
static VOID NEAR UpdateInfoFileName( NPMOVIEDATA pMovieData )
{
char szBuffer[MAX_NAME_LEN + 10]; // Buffer
char szFormat[20]; // Format buffer
lstrcpy( szFormat, "%s%s" );
if( pMovieData->wDuplicationIndex > 0 )
lstrcat( szFormat, ":%u" );
wsprintf( szBuffer, szFormat, (LPSTR) pMovieData->szMovieName,
(LPSTR) pMovieData->szMovieExt,
pMovieData->wDuplicationIndex );
AnsiUpper( szBuffer );
SetDlgItemText( pMovieData-> hwndGetInfo,
MOVIE_INFO_NAME, (LPSTR) szBuffer );
return;
}
// Function: DisplayCurrentSelection - Displays the current selection in
// the info dialog
// --------------------------------------------------------------------
// Parameters: NPMOVIEDATA pMovieData -> movie data struct
//
// Returns: VOID
// --------------------------------------------------------------------
static VOID NEAR DisplayCurrentSelection( NPMOVIEDATA pMovieData )
{
char szBuffer[100]; // Buffer
double fSelectionStart; // Beginning of selection
double fSelectionEnd; // End of selection
double fTimeScale; // Time scale of movie
if( ( ( fTimeScale = (double)
GetMovieTimeScale( pMovieData->mMovie )) != 0. ) &&
( pMovieData->trSelectionStart.value.dwLo != (DWORD) -1) &&
( pMovieData->trSelectionDuration.value.dwLo > 0L )) {
fSelectionStart = pMovieData->trSelectionStart.value.dwLo /
fTimeScale ;
fSelectionEnd = fSelectionStart +
pMovieData->trSelectionDuration.value.dwLo /
fTimeScale ;
sprintf( szBuffer, g.szSelectFormat, fSelectionStart, fSelectionEnd );
SetDlgItemText( pMovieData-> hwndGetInfo,
MOVIE_INFO_SELECTION, szBuffer );
}
else {
SetDlgItemText( pMovieData-> hwndGetInfo,
MOVIE_INFO_SELECTION, g.szNoSelection );
}
return;
}
// Function: ActionFilter - Used to filter the selection change message
// --------------------------------------------------------------------
// Parameters: MovieController mcController Movie controller
// UNIT psAction action parameter
// LPVOID lpParm DoAction parameter
// LONG lUserData User defined data
//
// Returns: BOOL TRUE if no further action
// FALSE if controller is to perform action
// --------------------------------------------------------------------
BOOL __export CALLBACK ActionFilter
( MovieController mcController, UINT psAction,
LPVOID lpParm, LONG lUserData )
{
NPMOVIEDATA pMovieData; // -> movie data struct
switch( psAction ) {
case mcActionControllerSizeChanged:
pMovieData = (NPMOVIEDATA) LOWORD( lUserData );
if( !pMovieData->bSettingControllerSize ) {
ResizeMovieAndWindow( (HWND) HIWORD( lUserData ),
FALSE, pMovieData, 0, 0 );
if( pMovieData->hwndGetInfo && !g.bUpdatingInfo ) { // Need to post message here because FALSE second
// parameter prevents ResizeMovie from being called
// by ResizeMovieAndWindow.
// WM_PLAYER_INFO_UPDATE is defined to be in
// the range WM_COALESCE_FIRST to WM_COALESCE_LAST
// which tells Windows to prevent duplicate messages
// from appearing in the queue.
PostMessage( pMovieData->hwndGetInfo,
WM_PLAYER_INFO_UPDATE, 0, 0L );
}
}
else {
pMovieData->bSettingControllerSize = FALSE;
}
break;
case mcActionSetSelectionBegin:
pMovieData = (NPMOVIEDATA) LOWORD( lUserData );
pMovieData->trSelectionStart = *( TimeRecord FAR *) lpParm;
break;
case mcActionSetSelectionDuration:
pMovieData = (NPMOVIEDATA) LOWORD( lUserData );
pMovieData->trSelectionDuration = *( TimeRecord FAR *) lpParm;
if( pMovieData->hwndGetInfo )
DisplayCurrentSelection( pMovieData );
break;
default:
break;
}
return FALSE;
}
// Function: InitializePopupMenus - Called just before the popup menus
// are displayed
// --------------------------------------------------------------------
// Parameters: HWND hwndMovie Handle of movie window
// HMENU hmenuPopup Handle of popup menu
// int nPopupIndex Index of popup
//
// Returns: LONG 0L if successful
// --------------------------------------------------------------------
static LONG NEAR InitializePopupMenus
( HWND hwndMovie, HMENU hmenuPopup, int nPopupIndex )
{
NPMOVIEDATA pMovieData; // -> movie data struct
LONG lControllerInfo; // Controller info
BOOL bLooping; // TRUE if looping
BOOL bPalindrome; // TRUE if looping palindrome
BOOL bPlaySelectionOnly; // TRUE if playing selection only
WORD wSelectedSize; // Nonzero if movie is a standard size
RECT rcMovie; // Movie rect
WORD wMovieWidth; // Width of movie
WORD wMovieHeight; // Height of movie
char szTitle[64]; // OLE Client doc title
char szItemFormat1[32]; // Item format string
char szItem1[128]; // New item string
char szItemFormat2[32]; // Item format string
char szItem2[128]; // New item string
if( !(pMovieData = (NPMOVIEDATA) GetWindowWord( hwndMovie, 0 ))) {
CommonTellUser( PlayerQueryResources(),
PLAYER_STRING_NOMOVIEDATA, PLAYER_STRING_CAPTION, MB_OK );
return 0L;
}
MCGetControllerInfo( pMovieData->mcMovieController,
&lControllerInfo );
// Decrement index if maximized since MDI adds a system menu item
// which puts count off by one
if( IsZoomed( hwndMovie ))
nPopupIndex--;
if( nPopupIndex == MENU_FILE_POS ) { // See if wnd is an activated client object
if( QTOLE_IsActiveObjectWnd
( PlayerQueryOleData(), hwndMovie, szTitle )) {
LoadString( PlayerQueryResources(),
PLAYER_STRING_OLECLOSE, szItemFormat1, sizeof( szItemFormat1 ));
wsprintf( szItem1, szItemFormat1, (LPSTR) szTitle );
LoadString( PlayerQueryResources(),
PLAYER_STRING_OLEEXIT, szItemFormat2, sizeof( szItemFormat2 ));
wsprintf( szItem2, szItemFormat2, (LPSTR) szTitle );
}
else {
LoadString( PlayerQueryResources(),
PLAYER_STRING_CLOSE, szItem1, sizeof( szItem1 ));
LoadString( PlayerQueryResources(),
PLAYER_STRING_EXIT, szItem2, sizeof( szItem2 ));
}
DeleteMenu( hmenuPopup, PLAYER_FILE_CLOSE, MF_BYCOMMAND );
InsertMenu( hmenuPopup, 1, MF_BYPOSITION,
PLAYER_FILE_CLOSE, szItem1 );
DeleteMenu( hmenuPopup, PLAYER_FILE_EXIT, MF_BYCOMMAND );
InsertMenu( hmenuPopup, (UINT) -1, MF_BYPOSITION,
PLAYER_FILE_EXIT, szItem2 );
EnableMenuItem( hmenuPopup, PLAYER_FILE_PRINT,
( pMovieData->bSoundOnly ||
(lControllerInfo & mcInfoIsPlaying)) ? MF_GRAYED: MF_ENABLED );
EnableMenuItem( hmenuPopup, PLAYER_FILE_PRTSETUP,
pMovieData->bSoundOnly ? MF_GRAYED: MF_ENABLED );
}
else if( nPopupIndex == MENU_EDIT_POS ) {
EnableMenuItem( hmenuPopup, PLAYER_EDIT_COPY,
( IsIconic( hwndMovie ) ||
( lControllerInfo & mcInfoIsPlaying )) ? MF_GRAYED: MF_ENABLED );
EnableMenuItem( hmenuPopup, PLAYER_EDIT_OPTIONS,
( IsIconic( hwndMovie ) ||
( lControllerInfo & mcInfoIsPlaying )) ? MF_GRAYED: MF_ENABLED );
}
else if( nPopupIndex == MENU_MOVIE_POS ) {
bLooping = (( lControllerInfo & mcInfoIsLooping ) != 0L );
bPalindrome = (( lControllerInfo & mcInfoIsInPalindrome ) != 0L );
CheckMenuItem( hmenuPopup, PLAYER_MOVIE_STOPATEND,
( bLooping || bPalindrome ) ? MF_UNCHECKED: MF_CHECKED );
CheckMenuItem( hmenuPopup, PLAYER_MOVIE_LOOP,
( bLooping && !bPalindrome ) ? MF_CHECKED: MF_UNCHECKED );
CheckMenuItem( hmenuPopup, PLAYER_MOVIE_BACKANDFORTH,
( bLooping && bPalindrome ) ? MF_CHECKED: MF_UNCHECKED );
// Toggle play selection only
MCDoAction( pMovieData->mcMovieController,
mcActionGetPlaySelection, (LPVOID) &bPlaySelectionOnly );
CheckMenuItem( hmenuPopup, PLAYER_MOVIE_PLAYSELONLY,
( bPlaySelectionOnly ) ? MF_CHECKED: MF_UNCHECKED );
EnableMenuItem( hmenuPopup, PLAYER_MOVIE_HALFSIZE,
pMovieData->bSoundOnly ? MF_GRAYED: MF_ENABLED );
EnableMenuItem( hmenuPopup, PLAYER_MOVIE_NORMALSIZE,
pMovieData->bSoundOnly ? MF_GRAYED: MF_ENABLED );
EnableMenuItem( hmenuPopup, PLAYER_MOVIE_DOUBLESIZE,
pMovieData->bSoundOnly ? MF_GRAYED: MF_ENABLED );
// Set selected size parameter if movie is a standard size
if( IsIconic( hwndMovie ))
wSelectedSize = 0;
else {
GetMovieBox( pMovieData->mMovie, &rcMovie );
wMovieWidth = rcMovie.right - rcMovie.left;
wMovieHeight = rcMovie.bottom - rcMovie.top;
if( ( wMovieWidth == pMovieData->idMovieInfo.width ) &&
( wMovieHeight == pMovieData->idMovieInfo.height ))
wSelectedSize = PLAYER_MOVIE_NORMALSIZE;
else if( ( wMovieWidth == pMovieData->idMovieInfo.width * 2 ) &&
( wMovieHeight == pMovieData->idMovieInfo.height * 2 ))
wSelectedSize = PLAYER_MOVIE_DOUBLESIZE;
else if( ( wMovieWidth == pMovieData->idMovieInfo.width / 2 ) &&
( wMovieHeight == pMovieData->idMovieInfo.height / 2 ))
wSelectedSize = PLAYER_MOVIE_HALFSIZE;
else
wSelectedSize = 0;
}
CheckMenuItem( hmenuPopup, PLAYER_MOVIE_HALFSIZE,
( !pMovieData->bSoundOnly &&
( wSelectedSize == PLAYER_MOVIE_HALFSIZE)) ?
MF_CHECKED: MF_UNCHECKED );
CheckMenuItem( hmenuPopup, PLAYER_MOVIE_NORMALSIZE,
( !pMovieData->bSoundOnly &&
( wSelectedSize == PLAYER_MOVIE_NORMALSIZE)) ?
MF_CHECKED: MF_UNCHECKED );
CheckMenuItem( hmenuPopup, PLAYER_MOVIE_DOUBLESIZE,
( !pMovieData->bSoundOnly &&
( wSelectedSize == PLAYER_MOVIE_DOUBLESIZE)) ?
MF_CHECKED: MF_UNCHECKED );
EnableMenuItem( hmenuPopup, PLAYER_MOVIE_SHOWPOSTER,
pMovieData->bSoundOnly ? MF_GRAYED: MF_ENABLED );
}
return 0L;
}
// Function: ResizeMovieAndWindow - Resizes the movie and window to the
// input width and height if flag is TRUE
// Otherwise resize window to match movie
// --------------------------------------------------------------------
// Parameters: HWND hwndMovie Handle of Movie window
// BOOL bResizeMovie TRUE if movie should be resized
// This will be FALSE when the grow
// box is used to resize since the
// movie will already be resized
// NPMOVIEDATA pMovieData -> to movie data struct
// WORD wMovieWidth width of movie
// WORD wMovieHeight height of movie
//
// Returns: LONG 0L if successful
// --------------------------------------------------------------------
static LONG NEAR ResizeMovieAndWindow( HWND hwndMovie, BOOL bResizeMovie,
NPMOVIEDATA pMovieData, WORD wMovieWidth, WORD wMovieHeight )
{
RECT rcWindow; // Window rect
RECT rcWindowPrev; // Prev Window rect
RECT rcBounds; // Bounds rect
POINT ptCorner; // Upper-Left corner of window
LONG lError; // Error return
POINT ptTemp[2]; // Temp array of points
if( bResizeMovie &&
( lError = ResizeMovie( pMovieData, wMovieWidth, wMovieHeight )))
return lError;
// Now Get the bounds rect. In this app, this is the same as the
// client rect of the window
MCGetControllerBoundsRect( pMovieData->mcMovieController, &rcBounds );
// Set about resizing window
// Save the prev window rect in client window coordinates
GetWindowRect( hwndMovie, &rcWindow );
MapWindowPoints( HWND_DESKTOP, PlayerQueryClientWindow(),
(LPPOINT) &rcWindow, 2 );
rcWindowPrev = rcWindow;
ptCorner = *((LPPOINT) &rcWindow );
// Adjust corner. This will only happen if window has been
// moved using the grow box
if( !bResizeMovie && ( rcBounds.left || rcBounds.top )) {
ptTemp[0].x = ptTemp[0].y = 0;
ptTemp[1] = *((LPPOINT) &rcBounds );
MapWindowPoints( hwndMovie, PlayerQueryClientWindow(), ptTemp, 2 );
ptCorner.x += ptTemp[1].x - ptTemp[0].x;
ptCorner.y += ptTemp[1].y - ptTemp[0].y;
}
rcWindow = rcBounds;
AdjustWindowRect( &rcWindow,
GetWindowLong( hwndMovie, GWL_STYLE ), FALSE );
// rcWindow contains the new size of the window.
// Now offset to the corrent UL corner
OffsetRect( &rcWindow, ptCorner.x - rcWindow.left,
ptCorner.y - rcWindow.top );
// If window rect has changed, resize after
// disabling the WM_SIZE processing
if( !EqualRect( &rcWindow, &rcWindowPrev )) {
pMovieData->bDisableSizeMsgProcessing = TRUE;
MoveWindow( hwndMovie, rcWindow.left, rcWindow.top,
rcWindow.right - rcWindow.left,
rcWindow.bottom - rcWindow.top, TRUE );
// If if happens that after resizing, the movie is smaller than
// minimum movie window size, resize movie to fill the window
GetClientRect( hwndMovie, &rcWindow );
if( !EqualRect( &rcWindow, &rcBounds )) {
pMovieData->bSettingControllerSize = TRUE;
MCSetControllerBoundsRect
( pMovieData->mcMovieController, &rcWindow );
}
}
return 0L;
}
// Function: ResizeMovie - Resizes the movie to the given size
// --------------------------------------------------------------------
// Parameters: NPMOVIEDATA pMovieData Pointer to movie data struct
// WORD wMovieWidth width of movie
// WORD wMovieHeight height of movie
//
// Returns: LONG 0L if successful
// --------------------------------------------------------------------
static LONG NEAR ResizeMovie( NPMOVIEDATA pMovieData,
WORD wMovieWidth, WORD wMovieHeight )
{
RECT rcBounds; // Controller bounds rect
// set based on input movie dimensions.
// Need to add in controller height for bounds rect
rcBounds.left = rcBounds.top = 0;
rcBounds.right = wMovieWidth;
rcBounds.bottom = wMovieHeight + g.wMovieControllerHeight;
pMovieData->bSettingControllerSize = TRUE;
MCSetControllerBoundsRect( pMovieData->mcMovieController, &rcBounds );
if( pMovieData->hwndGetInfo && !g.bUpdatingInfo ) { // WM_PLAYER_INFO_UPDATE is defined to be in the range WM_COALESCE_FIRST
// to WM_COALESCE_LAST which tells Windows to prevent duplicate messages
// from appearing in the queue.
PostMessage( pMovieData->hwndGetInfo, WM_PLAYER_INFO_UPDATE, 0, 0L );
}
return 0L;
}
// Function: UpdateGBBoundsRect - Updates the grow box bounds rect
// --------------------------------------------------------------------
// Parameters: HWND hwndMovie Handle of movie window
// NPMOVIEDATA pMovieData -> movie data struct
//
// Returns: VOID
// --------------------------------------------------------------------
static VOID NEAR UpdateGBBoundsRect( HWND hwndMovie, NPMOVIEDATA pMovieData )
{
GetClientRect( PlayerQueryFrameWindow(), &pMovieData->rcGrowBox );
MapWindowPoints( PlayerQueryFrameWindow(),
hwndMovie, (LPPOINT) &pMovieData->rcGrowBox , 2 );
MCDoAction( pMovieData->mcMovieController,
mcActionSetGrowBoxBounds, &pMovieData->rcGrowBox );
return;
}
// Function: MakeAnArialFont - Creates a logical font
// --------------------------------------------------------------------
// Parameters: HDC hdc Device context
// int nTextSize Size of font
//
// Returns: HFONT hFont
// Note: It is up to the caller to eventually delete this font
// --------------------------------------------------------------------
static HFONT NEAR MakeAnArialFont( HDC hdc, int nTextSize )
{
HFONT hFont; // Handle to created font
PLOGFONT plf; // -> to font struct
if( !(plf = (PLOGFONT) LocalAlloc( LPTR, sizeof( LOGFONT ))))
return NULL;
plf->lfHeight = nTextSize;
plf->lfWeight = FW_LIGHT;
plf->lfOutPrecision = OUT_TT_ONLY_PRECIS;
plf->lfPitchAndFamily = FF_SWISS;
LoadString( PlayerQueryResources(), PLAYER_STRING_FACENAME,
plf->lfFaceName, sizeof( plf->lfFaceName ));
hFont = CreateFontIndirect( plf );
LocalFree( (LOCALHANDLE) plf );
return hFont;
}
// Function: InitializeResize - Tests for constrained resize and
// sets dragging rect if true
// --------------------------------------------------------------------
// Parameters: HWND hwndMovie Handle of movie wnd
// NPMOVIEDATA pMovieData -> movie data struct
// WORD wHitTestCode NC hit test code
// POINT ptCursor Position of cursor in
// screen coordinates
//
// Returns: WORD wHitTestCode if in border, else 0
// --------------------------------------------------------------------
static WORD NEAR InitializeResize
( HWND hwndMovie, NPMOVIEDATA pMovieData,
WORD wHitTestCode, POINT ptCursor )
{
RECT rcClipCursor; // Rect used to clip motion of cursor
MINMAXINFO mmiMinMaxInfo; // Minmax info struct
GetWindowRect( hwndMovie, &g.rcResizeRect );
GetWindowRect( PlayerQueryClientWindow(), &rcClipCursor );
SetMinMaxInfo( hwndMovie, pMovieData, &mmiMinMaxInfo );
switch( wHitTestCode ) {
case HTTOP:
g.ptCursorOffset.x = 0;
g.ptCursorOffset.y = g.rcResizeRect.top - ptCursor.y;
rcClipCursor.bottom = g.rcResizeRect.bottom -
mmiMinMaxInfo.ptMinTrackSize.y;
break;
case HTBOTTOM:
g.ptCursorOffset.x = 0;
g.ptCursorOffset.y = g.rcResizeRect.bottom - ptCursor.y;
rcClipCursor.top = g.rcResizeRect.top +
mmiMinMaxInfo.ptMinTrackSize.y;
break;
case HTLEFT:
g.ptCursorOffset.x = g.rcResizeRect.left - ptCursor.x;
g.ptCursorOffset.y = 0;
rcClipCursor.right = g.rcResizeRect.right -
mmiMinMaxInfo.ptMinTrackSize.x;
break;
case HTRIGHT:
g.ptCursorOffset.x = g.rcResizeRect.right - ptCursor.x;
g.ptCursorOffset.y = 0;
rcClipCursor.left = g.rcResizeRect.left +
mmiMinMaxInfo.ptMinTrackSize.x;
break;
case HTTOPLEFT:
g.ptCursorOffset.x = g.rcResizeRect.left - ptCursor.x;
g.ptCursorOffset.y = g.rcResizeRect.top - ptCursor.y;
rcClipCursor.right = g.rcResizeRect.right -
mmiMinMaxInfo.ptMinTrackSize.x;
if( !pMovieData->bSoundOnly )
rcClipCursor.bottom = g.rcResizeRect.bottom -
mmiMinMaxInfo.ptMinTrackSize.y;
break;
case HTBOTTOMRIGHT:
g.ptCursorOffset.x = g.rcResizeRect.right - ptCursor.x;
g.ptCursorOffset.y = g.rcResizeRect.bottom - ptCursor.y;
rcClipCursor.left = g.rcResizeRect.left +
mmiMinMaxInfo.ptMinTrackSize.x;
if( !pMovieData->bSoundOnly )
rcClipCursor.top = g.rcResizeRect.top +
mmiMinMaxInfo.ptMinTrackSize.y;
break;
case HTTOPRIGHT:
g.ptCursorOffset.x = g.rcResizeRect.right - ptCursor.x;
g.ptCursorOffset.y = g.rcResizeRect.top - ptCursor.y;
rcClipCursor.left = g.rcResizeRect.left +
mmiMinMaxInfo.ptMinTrackSize.x;
if( !pMovieData->bSoundOnly )
rcClipCursor.bottom = g.rcResizeRect.bottom -
mmiMinMaxInfo.ptMinTrackSize.y;
break;
case HTBOTTOMLEFT:
g.ptCursorOffset.x = g.rcResizeRect.left - ptCursor.x;
g.ptCursorOffset.y = g.rcResizeRect.bottom - ptCursor.y;
rcClipCursor.right = g.rcResizeRect.right -
mmiMinMaxInfo.ptMinTrackSize.x;
if( !pMovieData->bSoundOnly )
rcClipCursor.top = g.rcResizeRect.top +
mmiMinMaxInfo.ptMinTrackSize.y;
break;
default:
return 0;
}
if( pMovieData->bSoundOnly ) {
SetCursor( g.hcursor = LoadCursor( NULL, IDC_SIZEWE ));
}
else {
SetCursor( g.hcursor = SetCursor( NULL ));
}
ClipCursor( &rcClipCursor );
g.wScaleWidth = max( pMovieData->idMovieInfo.width / 2, 1 );
g.wScaleHeight = max( pMovieData->idMovieInfo.height / 2, 1 );
return wHitTestCode;
}
// Function: MoveTheMovieResizeRect - Moves the resizing frame
// --------------------------------------------------------------------
// Parameters: HWND hwndMovie Handle of movie window
// NPMOVIEDATA pMovieData -> movie data struct
// WORD wHitTestCode Hit test code
// POINT ptCursor Current cursor position in
// screen coordinates
// BOOL bStarting TRUE if this is the first
// call of a drag
//
// Returns: VOID
// --------------------------------------------------------------------
static VOID NEAR MoveTheMovieResizeRect
( HWND hwndMovie, NPMOVIEDATA pMovieData,
WORD wHitTestCode, POINT ptCursor, BOOL bStarting )
{
RECT rcNewRect; // resize rect in screen coordinates
WORD wMovieWidth; // Movie width
WORD wMovieHeight; // Movie height
ptCursor.x += g.ptCursorOffset.x;
ptCursor.y += g.ptCursorOffset.y;
rcNewRect = g.rcResizeRect;
switch( wHitTestCode ) {
case HTTOP:
if( !ISKEYDOWN( VK_CONTROL ) && !ISKEYDOWN( VK_SHIFT )) {
rcNewRect.top = ptCursor.y;
}
else {
wMovieHeight = rcNewRect.bottom - ptCursor.y -
g.wTopAndBottom;
if( ISKEYDOWN( VK_CONTROL )) {
wMovieHeight = g.wScaleHeight *
max( wMovieHeight / g.wScaleHeight, 1 );
if( abs( wMovieHeight -
pMovieData->idMovieInfo.height ) <= 2 ) {
wMovieWidth = pMovieData->idMovieInfo.width;
wMovieHeight = pMovieData->idMovieInfo.height;
}
else {
wMovieWidth = MulDiv( wMovieHeight,
pMovieData->idMovieInfo.width,
pMovieData->idMovieInfo.height );
}
}
else {
wMovieWidth = MulDiv( wMovieHeight,
pMovieData->idMovieInfo.width,
pMovieData->idMovieInfo.height );
}
rcNewRect.right = rcNewRect.left + g.wSides + wMovieWidth;
rcNewRect.top = rcNewRect.bottom -
g.wTopAndBottom - wMovieHeight;
}
break;
case HTBOTTOM:
if( !ISKEYDOWN( VK_CONTROL ) && !ISKEYDOWN( VK_SHIFT )) {
rcNewRect.bottom = ptCursor.y;
}
else {
wMovieHeight = ptCursor.y - rcNewRect.top - g.wTopAndBottom;
if( ISKEYDOWN( VK_CONTROL )) {
wMovieHeight = g.wScaleHeight *
max( wMovieHeight / g.wScaleHeight, 1 );
if( abs( wMovieHeight -
pMovieData->idMovieInfo.height ) <= 2 ) {
wMovieWidth = pMovieData->idMovieInfo.width;
wMovieHeight = pMovieData->idMovieInfo.height;
}
else {
wMovieWidth = MulDiv( wMovieHeight,
pMovieData->idMovieInfo.width,
pMovieData->idMovieInfo.height );
}
}
else {
wMovieWidth = MulDiv( wMovieHeight,
pMovieData->idMovieInfo.width,
pMovieData->idMovieInfo.height );
}
rcNewRect.right = rcNewRect.left + g.wSides + wMovieWidth;
rcNewRect.bottom = rcNewRect.top +
g.wTopAndBottom + wMovieHeight;
}
break;
case HTLEFT:
if( pMovieData->bSoundOnly ||
( !ISKEYDOWN( VK_CONTROL ) && !ISKEYDOWN( VK_SHIFT ))) {
rcNewRect.left = ptCursor.x;
}
else {
wMovieWidth = rcNewRect.right - ptCursor.x - g.wSides;
if( ISKEYDOWN( VK_CONTROL )) {
wMovieWidth = g.wScaleWidth *
max( wMovieWidth / g.wScaleWidth, 1 );
if( abs( wMovieWidth -
pMovieData->idMovieInfo.width ) <= 2 ) {
wMovieWidth = pMovieData->idMovieInfo.width;
wMovieHeight = pMovieData->idMovieInfo.height;
}
else {
wMovieHeight = MulDiv( wMovieWidth,
pMovieData->idMovieInfo.height,
pMovieData->idMovieInfo.width );
}
}
else {
wMovieHeight = MulDiv( wMovieWidth,
pMovieData->idMovieInfo.height,
pMovieData->idMovieInfo.width );
}
rcNewRect.left = rcNewRect.right - g.wSides - wMovieWidth;
rcNewRect.bottom = rcNewRect.top +
g.wTopAndBottom + wMovieHeight;
}
break;
case HTRIGHT:
if( pMovieData->bSoundOnly ||
( !ISKEYDOWN( VK_CONTROL ) && !ISKEYDOWN( VK_SHIFT ))) {
rcNewRect.right = ptCursor.x;
}
else {
wMovieWidth = ptCursor.x - rcNewRect.left - g.wSides;
if( ISKEYDOWN( VK_CONTROL )) {
wMovieWidth = g.wScaleWidth *
max( wMovieWidth / g.wScaleWidth, 1 );
if( abs( wMovieWidth -
pMovieData->idMovieInfo.width ) <= 2 ) {
wMovieWidth = pMovieData->idMovieInfo.width;
wMovieHeight = pMovieData->idMovieInfo.height;
}
else {
wMovieHeight = MulDiv( wMovieWidth,
pMovieData->idMovieInfo.height,
pMovieData->idMovieInfo.width );
}
}
else {
wMovieHeight = MulDiv( wMovieWidth,
pMovieData->idMovieInfo.height,
pMovieData->idMovieInfo.width );
}
rcNewRect.right = rcNewRect.left + g.wSides + wMovieWidth;
rcNewRect.bottom = rcNewRect.top +
g.wTopAndBottom + wMovieHeight;
}
break;
case HTTOPLEFT:
if( pMovieData->bSoundOnly ) {
rcNewRect.left = ptCursor.x;
}
else if( !ISKEYDOWN( VK_CONTROL ) && !ISKEYDOWN( VK_SHIFT )) {
*((LPPOINT) &rcNewRect.left) = ptCursor;
}
else {
wMovieWidth = rcNewRect.right - ptCursor.x - g.wSides;
wMovieHeight = rcNewRect.bottom - ptCursor.y -
g.wTopAndBottom;
GetProportionalDimensions( pMovieData,
&wMovieWidth, &wMovieHeight, ISKEYDOWN( VK_CONTROL ));
rcNewRect.top = rcNewRect.bottom - wMovieHeight -
g.wTopAndBottom;
rcNewRect.left = rcNewRect.right - wMovieWidth - g.wSides;
}
break;
case HTBOTTOMRIGHT:
if( pMovieData->bSoundOnly ) {
rcNewRect.right = ptCursor.x;
}
else if( !ISKEYDOWN( VK_CONTROL ) && !ISKEYDOWN( VK_SHIFT )) {
*((LPPOINT) &rcNewRect.right) = ptCursor;
}
else {
wMovieWidth = ptCursor.x - rcNewRect.left - g.wSides;
wMovieHeight = ptCursor.y - rcNewRect.top - g.wTopAndBottom;
GetProportionalDimensions( pMovieData,
&wMovieWidth, &wMovieHeight, ISKEYDOWN( VK_CONTROL ));
rcNewRect.bottom = rcNewRect.top + wMovieHeight +
g.wTopAndBottom;
rcNewRect.right = rcNewRect.left + wMovieWidth + g.wSides;
}
break;
case HTTOPRIGHT:
if( pMovieData->bSoundOnly ) {
rcNewRect.right = ptCursor.x;
}
else if( !ISKEYDOWN( VK_CONTROL ) && !ISKEYDOWN( VK_SHIFT )) {
rcNewRect.right = ptCursor.x;
rcNewRect.top = ptCursor.y;
}
else {
wMovieWidth = ptCursor.x - rcNewRect.left - g.wSides;
wMovieHeight = rcNewRect.bottom -
ptCursor.y - g.wTopAndBottom;
GetProportionalDimensions( pMovieData,
&wMovieWidth, &wMovieHeight, ISKEYDOWN( VK_CONTROL ));
rcNewRect.top = rcNewRect.bottom - wMovieHeight -
g.wTopAndBottom;
rcNewRect.right = rcNewRect.left + wMovieWidth + g.wSides;
}
break;
case HTBOTTOMLEFT:
if( pMovieData->bSoundOnly ) {
rcNewRect.left = ptCursor.x;
}
else if( !ISKEYDOWN( VK_CONTROL ) && !ISKEYDOWN( VK_SHIFT )) {
rcNewRect.left = ptCursor.x;
rcNewRect.bottom = ptCursor.y;
}
else {
wMovieWidth = rcNewRect.right - ptCursor.x - g.wSides;
wMovieHeight = ptCursor.y - rcNewRect.top - g.wTopAndBottom;
GetProportionalDimensions( pMovieData,
&wMovieWidth, &wMovieHeight, ISKEYDOWN( VK_CONTROL ));
rcNewRect.bottom = rcNewRect.top + wMovieHeight +
g.wTopAndBottom;
rcNewRect.left = rcNewRect.right - wMovieWidth - g.wSides;
}
break;
}
if( bStarting ) {
g.rcResizeRect = rcNewRect;
g.bFatResizeBorder = IsNormalSize( &g.rcResizeRect, pMovieData );
DrawTheFrameRect( &g.rcResizeRect, g.bFatResizeBorder );
}
else if( !EqualRect( &g.rcResizeRect, &rcNewRect )) {
DrawTheFrameRect( &g.rcResizeRect, g.bFatResizeBorder );
g.rcResizeRect = rcNewRect;
g.bFatResizeBorder = IsNormalSize( &g.rcResizeRect, pMovieData );
DrawTheFrameRect( &g.rcResizeRect, g.bFatResizeBorder );
}
return;
}
// Function: AdjustForMinProportionalSize - Adjusts the final dimensions of a movie
// when a dimension is less than a minimum
// allowed size
// --------------------------------------------------------------------
// Parameters: HWND hwndMovie Handle of movie wnd
// NPMOVIEDATA pMovieData -> movie data struct
// LPWORD lpwWidth; -> window width
// LPWORD lpwHeight; -> window height
// BOOL bCtrlKeyDown TRUE if CONTROL key is down
//
// Returns: VOID
// --------------------------------------------------------------------
static VOID NEAR AdjustForMinProportionalSize
( HWND hwndMovie, NPMOVIEDATA pMovieData,
LPWORD lpwWidth, LPWORD lpwHeight, BOOL bCtrlKeyDown )
{
MINMAXINFO mmiMinMaxInfo; // Minmax info struct
WORD wMovieWidth; // Movie width
WORD wMovieHeight; // Movie height
SetMinMaxInfo( hwndMovie, pMovieData, &mmiMinMaxInfo );
// Add resizing borders
mmiMinMaxInfo.ptMinTrackSize.x += g.wSides;
mmiMinMaxInfo.ptMinTrackSize.y += g.wTBBorder;
if( ( *lpwWidth > (WORD) mmiMinMaxInfo.ptMinTrackSize.x ) &&
( *lpwHeight > (WORD) mmiMinMaxInfo.ptMinTrackSize.y ))
return;
if( *lpwWidth < (WORD) mmiMinMaxInfo.ptMinTrackSize.x ) {
*lpwWidth = mmiMinMaxInfo.ptMinTrackSize.x;
}
if( *lpwHeight < (WORD) mmiMinMaxInfo.ptMinTrackSize.y ) {
*lpwHeight = mmiMinMaxInfo.ptMinTrackSize.y;
}
// Mult by 10 because numbers may be small
wMovieWidth = ( *lpwWidth - g.wSides ) * 10;
wMovieHeight = ( *lpwHeight - g.wTopAndBottom ) * 10;
GetProportionalDimensions
( pMovieData, &wMovieWidth, &wMovieHeight, bCtrlKeyDown );
*lpwWidth = ( wMovieWidth + 10 * g.wSides ) / 10;
*lpwHeight = ( wMovieHeight + 10 * g.wTopAndBottom ) / 10;
return;
}
// Function: GetProportionalDimensions - Scales the dimensions of a movie to
// be in the same proportions as the
// original movie dimensions
// --------------------------------------------------------------------
// Parameters: NPMOVIEDATA pMovieData -> movie data struct
// PWORD pwMovieWidth -> current width
// PWORD pwMovieHeight -> current height
// BOOL bCtrlKeyDown TRUE if CONTROL key is down
//
// Returns: VOID
// --------------------------------------------------------------------
static VOID NEAR GetProportionalDimensions
( NPMOVIEDATA pMovieData, PWORD pwMovieWidth,
PWORD pwMovieHeight, BOOL bCtrlKeyDown )
{
WORD wTempHeight; // Temp height
wTempHeight = MulDiv( *pwMovieWidth,
pMovieData->idMovieInfo.height,
pMovieData->idMovieInfo.width );
if( wTempHeight >= *pwMovieHeight ) {
*pwMovieHeight = wTempHeight;
}
else {
*pwMovieWidth = MulDiv( *pwMovieHeight,
pMovieData->idMovieInfo.width,
pMovieData->idMovieInfo.height );
}
if( bCtrlKeyDown ) {
*pwMovieHeight = g.wScaleHeight *
max( *pwMovieHeight / g.wScaleHeight, 1 );
if( abs( *pwMovieHeight - pMovieData->idMovieInfo.height ) <= 2 ) {
*pwMovieWidth = pMovieData->idMovieInfo.width;
*pwMovieHeight = pMovieData->idMovieInfo.height;
}
else {
*pwMovieWidth = MulDiv( *pwMovieHeight,
pMovieData->idMovieInfo.width,
pMovieData->idMovieInfo.height );
}
}
return;
}
// Function: IsNormalSize - Determines if movie is normal size
// --------------------------------------------------------------------
// Parameters: RECT lprcResizeRect -> resize rect
// NPMOVIEDATA pMovieData -> movie data struct
//
// Returns: BOOL TRUE if input rect has the normal movie dimensions
// --------------------------------------------------------------------
static BOOL NEAR IsNormalSize
( LPRECT lprcResizeRect, NPMOVIEDATA pMovieData )
{
WORD wMovieWidth; // Current width of movie
WORD wMovieHeight; // Current height of movie
wMovieWidth = lprcResizeRect->right -
lprcResizeRect->left - g.wSides;
wMovieHeight = lprcResizeRect->bottom -
lprcResizeRect->top - g.wTopAndBottom;
return ( wMovieWidth == pMovieData->idMovieInfo.width ) &&
( wMovieHeight == pMovieData->idMovieInfo.height );
}
// Function: DrawTheFrameRect - Draws the resizing frame
// --------------------------------------------------------------------
// Parameters: RECT lprcResizeRect -> resize rect
// BOOL bFatBorder Flag to draw thicker border
//
// Returns: VOID
// --------------------------------------------------------------------
static VOID NEAR DrawTheFrameRect( LPRECT lprcResizeRect, BOOL bFatBorder )
{
HDC hdc; // DC of desktop
HBRUSH hbrushSave; // Prev brush
HBITMAP hbitmapCheckers; // Handle of checkerboard bitmap
WORD wWBorder; // Width of vertical border
WORD wHBorder; // Width of horizontal border
typedef BOOL ( CALLBACK* FFRAMEPROC ) (HDC, LPRECT, int, int, DWORD);
static WORD wBorderWidth; // Width of vertical resize border
static WORD wBorderHeight; // Height of horizontal resize border
static FFRAMEPROC lpfnFastWindowFrame; // -> FastWindowFrame()
static HBRUSH hbrushCheckers; // Handle to frame brush
// FastWindowFrame() is an undocumented Windows function
// described in "Undocumented Windows" by Andrew Schulman,
// David Maxey and Matt Pietrek, Addison Wesley, 1992.
if( lprcResizeRect == NULL ) // Clean up
{
if( hbrushCheckers ) {
DeleteObject( hbrushCheckers );
hbrushCheckers = NULL;
}
return;
}
if( !lpfnFastWindowFrame ) {
lpfnFastWindowFrame = (FFRAMEPROC) GetProcAddress(
GetModuleHandle( "GDI" ), "FASTWINDOWFRAME" );
wBorderWidth = GetSystemMetrics( SM_CXFRAME ) - 1;
wBorderHeight = GetSystemMetrics( SM_CXFRAME ) - 1;
}
if( !hbrushCheckers &&
( hbitmapCheckers = LoadBitmap( PlayerQueryInstance(),
MAKEINTRESOURCE( PLAYER_CHECKERS_BITMAP )))) {
hbrushCheckers = CreatePatternBrush( hbitmapCheckers );
DeleteObject( hbitmapCheckers );
}
if( hdc = GetDC( NULL )) {
if( lpfnFastWindowFrame ) {
if( hbrushCheckers )
hbrushSave = SelectObject( hdc, hbrushCheckers );
else
hbrushSave = SelectObject( hdc,
GetStockObject( GRAY_BRUSH ));
wWBorder = wBorderWidth + ( bFatBorder? 2: 0);
wHBorder = wBorderHeight + ( bFatBorder? 2: 0);
if( !( *lpfnFastWindowFrame ) ( hdc, lprcResizeRect,
wWBorder, wHBorder, PATINVERT )) { // Use PatBlt when FastWindowFrame fails
ExcludeClipRect( hdc,
lprcResizeRect->left + wWBorder,
lprcResizeRect->top + wHBorder,
lprcResizeRect->right - wWBorder,
lprcResizeRect->bottom - wHBorder );
PatBlt( hdc, lprcResizeRect->left,
lprcResizeRect->top,
lprcResizeRect->right - lprcResizeRect->left,
lprcResizeRect->bottom - lprcResizeRect->top,
PATINVERT );
}
if( hbrushSave )
SelectObject( hdc, hbrushSave );
}
else {
DrawFocusRect( hdc, lprcResizeRect );
}
ReleaseDC( NULL, hdc );
}
return;
}
// Function: SubclassTheGrowBox - Subclass the movie controller grow box
// --------------------------------------------------------------------
// Parameters: HWND hwndMovie Handle of movie wnd
// NPMOVIEDATA pMovieData -> movie data struct
//
// Returns: BOOL TRUE if successful
// --------------------------------------------------------------------
static BOOL NEAR SubclassTheGrowBox
( HWND hwndMovie, NPMOVIEDATA pMovieData )
{
WNDENUMPROC lpfnEnumProc; // -> enumeration proc
if( lpfnEnumProc = (WNDENUMPROC) MakeProcInstance
( (FARPROC) MovieChildEnumProc, PlayerQueryInstance())) {
EnumChildWindows( hwndMovie, lpfnEnumProc,
MAKELONG( pMovieData, 0 ));
FreeProcInstance( (FARPROC) lpfnEnumProc );
return pMovieData->bGrowBoxSubclassed;
}
return FALSE;
}
// Function: MovieChildEnumProc - Movie child enumeration proc
// --------------------------------------------------------------------
// Parameters: As required by Microsoft Windows
//
// Returns: As required by Microsoft Windows
// --------------------------------------------------------------------
BOOL __export CALLBACK MovieChildEnumProc
( HWND hwndChild, LPARAM lParam )
{
char szClassName[50]; // Class name buffer
// The grow box class name can be found by using the enumeration
// routine to list all the names
#define GROWBOXCLASSNAME "MCGrowBox"
if( GetClassName( hwndChild,
szClassName, sizeof( szClassName )) &&
!lstrcmpi( GROWBOXCLASSNAME, szClassName )) {
if( g.lpNewGBProc ||
( g.lpNewGBProc = (WNDPROC) MakeProcInstance
( (FARPROC) GBSubClassProc, PlayerQueryInstance()))) {
if( g.lpOldGBProc = (WNDPROC) SetWindowLong
( hwndChild, GWL_WNDPROC, (LONG) g.lpNewGBProc )) {
((NPMOVIEDATA) LOWORD( lParam ))->
bGrowBoxSubclassed = TRUE;
}
}
return FALSE;
}
return TRUE;
}
// Function: GBSubClassProc - Movie controller grow box subclass
// --------------------------------------------------------------------
// Parameters: As required by Microsoft Windows
//
// Returns: As required by Microsoft Windows
// --------------------------------------------------------------------
LONG __export CALLBACK GBSubClassProc
( HWND hwndGrowBox, UINT message, WPARAM wParam, LPARAM lParam )
{
POINT ptCursor; // Cursor position
if( g.hwndMaximizedMovie && ( message == WM_LBUTTONDOWN )) {
ptCursor = MAKEPOINT( lParam );
ClientToScreen( hwndGrowBox, &ptCursor );
InitMaxWndGrowBoxResize( hwndGrowBox, ptCursor );
SetCapture( g.hwndMaximizedMovie );
g.bCapturedGrowBox = TRUE;
return 0L;
}
return CallWindowProc
( g.lpOldGBProc, hwndGrowBox, message, wParam, lParam );
}
// Function: InitMaxWndGrowBoxResize - Initializes the maximized window grow
// box resizing
// --------------------------------------------------------------------
// Parameters: HWND hwndGrowBox Handle of grow box
// POINT ptCursor Position of cursor in screen coords.
//
// Returns: BOOL TRUE if successful
// --------------------------------------------------------------------
static BOOL NEAR InitMaxWndGrowBoxResize
( HWND hwndGrowBox, POINT ptCursor )
{
RECT rcClipCursor; // Clip cursor rect
HDC hdc; // DC of desktop
GetWindowRect( PlayerQueryFrameWindow(), &g.rcResizeRect );
g.ptCursorOffset.x = g.rcResizeRect.right - ptCursor.x;
g.ptCursorOffset.y = g.rcResizeRect.bottom - ptCursor.y;
rcClipCursor.left = g.rcResizeRect.left +
GetSystemMetrics( SM_CXMINTRACK ) - g.ptCursorOffset.x;
rcClipCursor.top = g.rcResizeRect.top +
GetSystemMetrics( SM_CYMINTRACK ) - g.ptCursorOffset.y;
// Offset the clip cursor rect to keep frame on screen
if( hdc = GetDC( NULL )) {
rcClipCursor.right =
GetDeviceCaps( hdc, HORZRES ) - g.ptCursorOffset.x;
rcClipCursor.bottom =
GetDeviceCaps( hdc, VERTRES ) - g.ptCursorOffset.y;
ReleaseDC( NULL, hdc );
}
else {
rcClipCursor.right = 0x7fff;
rcClipCursor.bottom = 0x7fff;
}
ClipCursor( &rcClipCursor );
DrawTheFrameRect( &g.rcResizeRect, FALSE );
return TRUE;
}
// Function: MoveTheFrameResizeRect - Moves the resizing frame during
// maximized wnd grow box resizing
// --------------------------------------------------------------------
// Parameters: HWND hwndMovie Handle of movie wnd
// POINT ptCursor Current cursor position in
// screen coordinates
//
// Returns: VOID
// --------------------------------------------------------------------
static VOID NEAR MoveTheFrameResizeRect
( HWND hwndMovie, POINT ptCursor )
{
RECT rcNewRect; // resize rect in screen coordinates
ptCursor.x += g.ptCursorOffset.x;
ptCursor.y += g.ptCursorOffset.y;
rcNewRect = g.rcResizeRect;
*((LPPOINT) &rcNewRect.right) = ptCursor;
if( !EqualRect( &g.rcResizeRect, &rcNewRect )) {
DrawTheFrameRect( &g.rcResizeRect, FALSE );
g.rcResizeRect = rcNewRect;
DrawTheFrameRect( &g.rcResizeRect, FALSE );
}
return;
}
// Function: FixUpMovieTiling - Sets the dimensions of the movie
// window when tiling
// --------------------------------------------------------------------
// Parameters: HWND hwndMovie Handle of movie wnd
// NPMOVIEDATA pMovieData -> movie data struct
// LPWINDOWPOS lpwpWndPos -> WINDOWPOS struct
//
// Returns: LONG Always 0L
// --------------------------------------------------------------------
static LONG NEAR FixUpMovieTiling
( HWND hwndMovie, NPMOVIEDATA pMovieData, LPWINDOWPOS lpwpWndPos )
{
WORD wMovieWidthMDI; // Width of tile region
WORD wMovieHeightMDI; // Height of tile region
WORD wTemp; // Temp
MINMAXINFO mmiMinMaxInfo; // MinMax info struct
if( pMovieData->bSoundOnly ) {
SetMinMaxInfo( hwndMovie, pMovieData, &mmiMinMaxInfo );
lpwpWndPos->cx =
max( mmiMinMaxInfo.ptMinTrackSize.x,
min( (int) g.wSoundOnlyDefWidth, lpwpWndPos->cx ));
lpwpWndPos->cy = mmiMinMaxInfo.ptMaxTrackSize.y;
return 0L;
}
wMovieWidthMDI = lpwpWndPos->cx - g.wSides;
wMovieHeightMDI = lpwpWndPos->cy - g.wTopAndBottom;
if( ( wMovieWidthMDI >= pMovieData->idMovieInfo.width ) &&
( wMovieHeightMDI >= pMovieData->idMovieInfo.height )) {
lpwpWndPos->cx = pMovieData->idMovieInfo.width + g.wSides;
lpwpWndPos->cy = pMovieData->idMovieInfo.height +
g.wTopAndBottom;
}
else // Try setting height and calc width
{
wTemp = MulDiv( wMovieHeightMDI,
pMovieData->idMovieInfo.width,
pMovieData->idMovieInfo.height );
// If it fits, we are done
if( wTemp <= wMovieWidthMDI ) {
lpwpWndPos->cx = wTemp + g.wSides;
}
else // Set width and calc height
{
wTemp = MulDiv( wMovieWidthMDI,
pMovieData->idMovieInfo.height,
pMovieData->idMovieInfo.width );
lpwpWndPos->cy = wTemp + g.wTopAndBottom;
}
// Now check for min allowed proportional size
AdjustForMinProportionalSize( hwndMovie, pMovieData,
&lpwpWndPos->cx, &lpwpWndPos->cy, FALSE );
}
return 0L;
}
// Function: SetOptionsDefaults - Set option defaults
// --------------------------------------------------------------------
// Parameters: HWND hwndMovie Movie hwnd
// NPMOVIEDATA pMovieData -> movie data struct
//
// Returns: VOID
// --------------------------------------------------------------------
static VOID NEAR SetOptionsDefaults
( HWND hwndMovie, NPMOVIEDATA pMovieData )
{ // Preset copy struct parameters that do not change
pMovieData->qtoleOptions.lStructSize = sizeof( QTOLE_OPTIONSMOVIE );
pMovieData->qtoleOptions.lVersion = VERSION_1;
pMovieData->qtoleOptions.wObjectType = MOVIE_OBJECT;
pMovieData->qtoleOptions.hwndObject = hwndMovie;
pMovieData->qtoleOptions.mMovie = pMovieData->mMovie;
pMovieData->qtoleOptions.bSoundOnlyMovie = pMovieData->bSoundOnly;
pMovieData->qtoleOptions.lfxRate = DEFAULT_RATE;
pMovieData->qtoleOptions.sizeNormal.cx = pMovieData->idMovieInfo.width;
pMovieData->qtoleOptions.sizeNormal.cy = pMovieData->idMovieInfo.height;
pMovieData->qtoleOptions.tvMovieDuration =
GetMovieDuration( pMovieData->mMovie );
// This routine queries qtw.ini for defaults
PlayerGetDefaultOptions( &pMovieData->qtoleOptions );
if( pMovieData->qtoleOptions.bSizeHalf ) {
pMovieData->qtoleOptions.sizeCurrent.cx =
pMovieData->qtoleOptions.sizeNormal.cx / 2;
pMovieData->qtoleOptions.sizeCurrent.cy =
pMovieData->qtoleOptions.sizeNormal.cy / 2;
}
else if( pMovieData->qtoleOptions.bSizeDouble ) {
pMovieData->qtoleOptions.sizeCurrent.cx =
pMovieData->qtoleOptions.sizeNormal.cx * 2;
pMovieData->qtoleOptions.sizeCurrent.cy =
pMovieData->qtoleOptions.sizeNormal.cy * 2;
}
else // Set to normal size if not half or double
{
pMovieData->qtoleOptions.sizeCurrent =
pMovieData->qtoleOptions.sizeNormal;
}
lstrcpy( pMovieData->qtoleOptions.szCaption, pMovieData->szMovieName );
lstrcat( pMovieData->qtoleOptions.szCaption, pMovieData->szMovieExt );
return;
}
// Function: UpdateMovieForOptions - Sets movie options according to values
// set in options dialog
// --------------------------------------------------------------------
// Parameters: HWND hwndMovie; Movie window handle
// NPMOVIEDATA pMovieData; Movie data structure
// BOOL bCalledByOLE TRUE if called by ole callback func.
//
// Returns: None
// --------------------------------------------------------------------
VOID FAR UpdateMovieForOptions
( HWND hwndMovie, NPMOVIEDATA pMovieData, BOOL bCalledByOLE )
{
TimeRecord trTime;
if( pMovieData->qtoleOptions.bLoop )
SendMessage( hwndMovie, WM_COMMAND, PLAYER_MOVIE_LOOP, 0L );
else if( pMovieData->qtoleOptions.bLoopPalindrome )
SendMessage( hwndMovie, WM_COMMAND, PLAYER_MOVIE_BACKANDFORTH, 0L );
else
SendMessage( hwndMovie, WM_COMMAND, PLAYER_MOVIE_STOPATEND, 0L );
MCDoAction( pMovieData->mcMovieController,
mcActionSetPlaySelection,
(LPVOID) pMovieData->qtoleOptions.bPlaySelectionOnly );
if( pMovieData->qtoleOptions.bSizeHalf )
SendMessage( hwndMovie, WM_COMMAND, PLAYER_MOVIE_HALFSIZE, 0L );
else if( pMovieData->qtoleOptions.bSizeNormal )
SendMessage( hwndMovie, WM_COMMAND, PLAYER_MOVIE_NORMALSIZE, 0L );
else if( pMovieData->qtoleOptions.bSizeDouble )
SendMessage( hwndMovie, WM_COMMAND, PLAYER_MOVIE_DOUBLESIZE, 0L );
else if( bCalledByOLE )
ResizeMovieAndWindow( hwndMovie, TRUE, pMovieData,
pMovieData->qtoleOptions.sizeCurrent.cx,
pMovieData->qtoleOptions.sizeCurrent.cy );
if( bCalledByOLE ) {
trTime.value.dwHi = 0L;
trTime.value.dwLo = pMovieData->qtoleOptions.tvDisplayFrame;
trTime.scale = GetMovieTimeScale( pMovieData->mMovie );
trTime.base = TIMEBASE_DEFAULT;
MCDoAction( pMovieData->mcMovieController,
mcActionGoToTime, (LPVOID) &trTime );
MCDoAction( pMovieData->mcMovieController,
mcActionSetSelectionBegin,
(LPVOID) &pMovieData->qtoleOptions.trSelStart );
MCDoAction( pMovieData->mcMovieController,
mcActionSetSelectionDuration,
(LPVOID) &pMovieData->qtoleOptions.trSelDuration );
}
return;
}
// Function: PopulateOptionsStruct - Populates the options structure
// --------------------------------------------------------------------
// Parameters: HWND hwndMovie HWND of movie
// NPMOVIEDATA pMovieData Movie data structure
//
// Returns: None
// --------------------------------------------------------------------
static VOID NEAR PopulateOptionsStruct( HWND hwndMovie, NPMOVIEDATA pMovieData )
{
BOOL bLoop; // Looping flag
BOOL bLoopPalindrome; // Loop palindrome flag
RECT rcMovie; // Movie rectangle
WORD wMovieWidth; // Movie width
WORD wMovieHeight; // Movie height
TimeRecord trMovieTime; // Movie time.. not used
// Update these each time in case they get NULLed somewhere
pMovieData->qtoleOptions.hwndObject = hwndMovie;
pMovieData->qtoleOptions.mMovie = pMovieData->mMovie;
MCDoAction( pMovieData->mcMovieController,
mcActionGetLooping, (LPVOID) &bLoop );
MCDoAction( pMovieData->mcMovieController,
mcActionGetLoopIsPalindrome, (LPVOID) &bLoopPalindrome );
pMovieData->qtoleOptions.bLoop = FALSE;
pMovieData->qtoleOptions.bLoopPalindrome = FALSE;
if( bLoop ) {
if( bLoopPalindrome )
pMovieData->qtoleOptions.bLoopPalindrome = TRUE;
else
pMovieData->qtoleOptions.bLoop = TRUE;
}
MCDoAction( pMovieData->mcMovieController,
mcActionGetPlaySelection,
(LPVOID) &pMovieData->qtoleOptions.bPlaySelectionOnly );
if( pMovieData->qtoleOptions.bPlaySelectionOnly ) {
pMovieData->qtoleOptions.trSelStart = pMovieData->trSelectionStart;
pMovieData->qtoleOptions.trSelDuration =
pMovieData->trSelectionDuration;
}
else {
memset( &pMovieData->qtoleOptions.trSelStart,
0, sizeof( TimeRecord ));
memset( &pMovieData->qtoleOptions.trSelDuration,
0, sizeof( TimeRecord ));
}
GetMovieBox( pMovieData->mMovie, &rcMovie );
wMovieWidth = rcMovie.right - rcMovie.left;
wMovieHeight = rcMovie.bottom - rcMovie.top;
pMovieData->qtoleOptions.sizeCurrent.cx = wMovieWidth;
pMovieData->qtoleOptions.sizeCurrent.cy = wMovieHeight;
if( !pMovieData->qtoleOptions.bSoundOnlyMovie ) {
if( !pMovieData->qtoleOptions.bCopyCurrentFrame ) {
pMovieData->qtoleOptions.tvDisplayFrame =
GetMoviePosterTime( pMovieData->mMovie );
}
else {
pMovieData->qtoleOptions.tvDisplayFrame =
GetMovieTime( pMovieData->mMovie, &trMovieTime );
}
}
else {
pMovieData->qtoleOptions.tvDisplayFrame = 0;
}
return;
}
// This function is a query function called by other modules
// Function: PlayerQueryActiveMovieName - Query name of active movie
// --------------------------------------------------------------------
// Parameters: LPSTR lpBuffer string buffer
//
// Returns: LPSTR lpBuffer Name of active movie
// --------------------------------------------------------------------
LPSTR FAR PlayerQueryActiveMovieName( LPSTR lpBuffer )
{
HWND hwndMovie; // Handle to active window
NPMOVIEDATA pMovieData; // ->movie data struct
hwndMovie = (HWND) SendMessage
( PlayerQueryClientWindow(), WM_MDIGETACTIVE, 0, 0L );
*lpBuffer = 0;
if( pMovieData = (NPMOVIEDATA) GetWindowWord( hwndMovie, 0 ))
lstrcpy( lpBuffer, pMovieData->szMovieName );
return lpBuffer;
}